]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(createRenderer): handle errors in function refs (#403)
authorDmitry Sharshakov <d3dx12.xx@gmail.com>
Mon, 28 Oct 2019 16:03:30 +0000 (19:03 +0300)
committerEvan You <yyx990803@gmail.com>
Mon, 28 Oct 2019 16:03:30 +0000 (12:03 -0400)
packages/runtime-core/__tests__/errorHandling.spec.ts
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/errorHandling.ts

index 6f3f9c6aa9cfbb19947e5e2b9561ff592897b951..feb2b30c8793e57d36436b8b73c91530e41f45ee 100644 (file)
@@ -7,7 +7,8 @@ import {
   watch,
   ref,
   nextTick,
-  mockWarn
+  mockWarn,
+  createComponent
 } from '@vue/runtime-test'
 
 describe('error handling', () => {
@@ -208,6 +209,29 @@ describe('error handling', () => {
     expect(fn).toHaveBeenCalledWith(err, 'render function')
   })
 
+  test('in function ref', () => {
+    const err = new Error('foo')
+    const ref = () => {
+      throw err
+    }
+    const fn = jest.fn()
+
+    const Comp = {
+      setup() {
+        onErrorCaptured((err, instance, info) => {
+          fn(err, info)
+          return true
+        })
+        return () => h(Child)
+      }
+    }
+
+    const Child = createComponent(() => () => h('div', { ref }))
+
+    render(h(Comp), nodeOps.createElement('div'))
+    expect(fn).toHaveBeenCalledWith(err, 'ref function')
+  })
+
   test('in watch (simple usage)', () => {
     const err = new Error('foo')
     const fn = jest.fn()
index 3473f53bd1423718133127dbb1bb67a634b6bf86..009329dcf37317a6d9672c904e639548a37070eb 100644 (file)
@@ -52,7 +52,7 @@ import {
   createSuspenseBoundary,
   normalizeSuspenseChildren
 } from './suspense'
-import { handleError, ErrorCodes } from './errorHandling'
+import { handleError, ErrorCodes, callWithErrorHandling } from './errorHandling'
 
 const prodEffectOptions = {
   scheduler: queueJob
@@ -1852,7 +1852,7 @@ export function createRenderer<
     } else if (isRef(ref)) {
       ref.value = value
     } else if (isFunction(ref)) {
-      ref(value, refs)
+      callWithErrorHandling(ref, parent, ErrorCodes.FUNCTION_REF, [value, refs])
     } else if (__DEV__) {
       warn('Invalid template ref type:', value, `(${typeof value})`)
     }
index d576ff4a19a03b87be83253e7011e09840d71c8d..cc5e42c4a2a3306d43ff66b1d17a2153aa1116f2 100644 (file)
@@ -16,6 +16,7 @@ export const enum ErrorCodes {
   DIRECTIVE_HOOK,
   APP_ERROR_HANDLER,
   APP_WARN_HANDLER,
+  FUNCTION_REF,
   SCHEDULER
 }
 
@@ -43,6 +44,7 @@ export const ErrorTypeStrings: Record<number | string, string> = {
   [ErrorCodes.DIRECTIVE_HOOK]: 'directive hook',
   [ErrorCodes.APP_ERROR_HANDLER]: 'app errorHandler',
   [ErrorCodes.APP_WARN_HANDLER]: 'app warnHandler',
+  [ErrorCodes.FUNCTION_REF]: 'ref function',
   [ErrorCodes.SCHEDULER]:
     'scheduler flush. This is likely a Vue internals bug. ' +
     'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue'