feat(createRenderer): handle errors in function refs (#403)

This commit is contained in:
Dmitry Sharshakov 2019-10-28 19:03:30 +03:00 committed by Evan You
parent 34989ef7fe
commit 325e15ef41
3 changed files with 29 additions and 3 deletions

View 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()

View 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})`)
}

View 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'