defineComponent,
watchEffect
} from '@vue/runtime-test'
-import { setErrorRecovery } from '../src/errorHandling'
describe('error handling', () => {
- beforeEach(() => {
- setErrorRecovery(true)
- })
-
- afterEach(() => {
- setErrorRecovery(false)
- })
-
test('propagation', () => {
const err = new Error('foo')
const fn = jest.fn()
})
it('should warn unhandled', () => {
- const onError = jest.spyOn(console, 'error')
- onError.mockImplementation(() => {})
const groupCollapsed = jest.spyOn(console, 'groupCollapsed')
groupCollapsed.mockImplementation(() => {})
const log = jest.spyOn(console, 'log')
render() {}
}
- render(h(Comp), nodeOps.createElement('div'))
+ let caughtError
+ try {
+ render(h(Comp), nodeOps.createElement('div'))
+ } catch (caught) {
+ caughtError = caught
+ }
expect(fn).toHaveBeenCalledWith(err, 'setup function')
expect(
`Unhandled error during execution of setup function`
).toHaveBeenWarned()
- expect(onError).toHaveBeenCalledWith(err)
+ expect(caughtError).toBe(err)
- onError.mockRestore()
groupCollapsed.mockRestore()
log.mockRestore()
})
logError(err, type, contextVNode)
}
-// Test-only toggle for testing the unhandled warning behavior
-let forceRecover = false
-export function setErrorRecovery(value: boolean) {
- forceRecover = value
-}
-
function logError(err: unknown, type: ErrorTypes, contextVNode: VNode | null) {
- // default behavior is crash in prod & test, recover in dev.
- if (__DEV__ && (forceRecover || !__TEST__)) {
+ if (__DEV__) {
const info = ErrorTypeStrings[type]
if (contextVNode) {
pushWarningContext(contextVNode)
}
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`)
- console.error(err)
if (contextVNode) {
popWarningContext()
}
- } else {
+ // crash in dev so it's more noticeable
throw err
+ } else {
+ // recover in prod to reduce the impact on end-user
+ console.error(err)
}
}