feat(createRenderer): handle errors in function refs (#403)
This commit is contained in:
parent
34989ef7fe
commit
325e15ef41
@ -7,7 +7,8 @@ import {
|
|||||||
watch,
|
watch,
|
||||||
ref,
|
ref,
|
||||||
nextTick,
|
nextTick,
|
||||||
mockWarn
|
mockWarn,
|
||||||
|
createComponent
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
|
|
||||||
describe('error handling', () => {
|
describe('error handling', () => {
|
||||||
@ -208,6 +209,29 @@ describe('error handling', () => {
|
|||||||
expect(fn).toHaveBeenCalledWith(err, 'render function')
|
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)', () => {
|
test('in watch (simple usage)', () => {
|
||||||
const err = new Error('foo')
|
const err = new Error('foo')
|
||||||
const fn = jest.fn()
|
const fn = jest.fn()
|
||||||
|
@ -52,7 +52,7 @@ import {
|
|||||||
createSuspenseBoundary,
|
createSuspenseBoundary,
|
||||||
normalizeSuspenseChildren
|
normalizeSuspenseChildren
|
||||||
} from './suspense'
|
} from './suspense'
|
||||||
import { handleError, ErrorCodes } from './errorHandling'
|
import { handleError, ErrorCodes, callWithErrorHandling } from './errorHandling'
|
||||||
|
|
||||||
const prodEffectOptions = {
|
const prodEffectOptions = {
|
||||||
scheduler: queueJob
|
scheduler: queueJob
|
||||||
@ -1852,7 +1852,7 @@ export function createRenderer<
|
|||||||
} else if (isRef(ref)) {
|
} else if (isRef(ref)) {
|
||||||
ref.value = value
|
ref.value = value
|
||||||
} else if (isFunction(ref)) {
|
} else if (isFunction(ref)) {
|
||||||
ref(value, refs)
|
callWithErrorHandling(ref, parent, ErrorCodes.FUNCTION_REF, [value, refs])
|
||||||
} else if (__DEV__) {
|
} else if (__DEV__) {
|
||||||
warn('Invalid template ref type:', value, `(${typeof value})`)
|
warn('Invalid template ref type:', value, `(${typeof value})`)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ export const enum ErrorCodes {
|
|||||||
DIRECTIVE_HOOK,
|
DIRECTIVE_HOOK,
|
||||||
APP_ERROR_HANDLER,
|
APP_ERROR_HANDLER,
|
||||||
APP_WARN_HANDLER,
|
APP_WARN_HANDLER,
|
||||||
|
FUNCTION_REF,
|
||||||
SCHEDULER
|
SCHEDULER
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ export const ErrorTypeStrings: Record<number | string, string> = {
|
|||||||
[ErrorCodes.DIRECTIVE_HOOK]: 'directive hook',
|
[ErrorCodes.DIRECTIVE_HOOK]: 'directive hook',
|
||||||
[ErrorCodes.APP_ERROR_HANDLER]: 'app errorHandler',
|
[ErrorCodes.APP_ERROR_HANDLER]: 'app errorHandler',
|
||||||
[ErrorCodes.APP_WARN_HANDLER]: 'app warnHandler',
|
[ErrorCodes.APP_WARN_HANDLER]: 'app warnHandler',
|
||||||
|
[ErrorCodes.FUNCTION_REF]: 'ref function',
|
||||||
[ErrorCodes.SCHEDULER]:
|
[ErrorCodes.SCHEDULER]:
|
||||||
'scheduler flush. This is likely a Vue internals bug. ' +
|
'scheduler flush. This is likely a Vue internals bug. ' +
|
||||||
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue'
|
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user