refactor(runtime-core): adjust error handling behavior
- Crash in dev to make the errors more noticeable - Recover in prod to reduce impact on end users
This commit is contained in:
parent
678364802d
commit
3cc768f9f2
@ -10,17 +10,8 @@ import {
|
|||||||
defineComponent,
|
defineComponent,
|
||||||
watchEffect
|
watchEffect
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import { setErrorRecovery } from '../src/errorHandling'
|
|
||||||
|
|
||||||
describe('error handling', () => {
|
describe('error handling', () => {
|
||||||
beforeEach(() => {
|
|
||||||
setErrorRecovery(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
setErrorRecovery(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('propagation', () => {
|
test('propagation', () => {
|
||||||
const err = new Error('foo')
|
const err = new Error('foo')
|
||||||
const fn = jest.fn()
|
const fn = jest.fn()
|
||||||
@ -470,8 +461,6 @@ describe('error handling', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should warn unhandled', () => {
|
it('should warn unhandled', () => {
|
||||||
const onError = jest.spyOn(console, 'error')
|
|
||||||
onError.mockImplementation(() => {})
|
|
||||||
const groupCollapsed = jest.spyOn(console, 'groupCollapsed')
|
const groupCollapsed = jest.spyOn(console, 'groupCollapsed')
|
||||||
groupCollapsed.mockImplementation(() => {})
|
groupCollapsed.mockImplementation(() => {})
|
||||||
const log = jest.spyOn(console, 'log')
|
const log = jest.spyOn(console, 'log')
|
||||||
@ -496,14 +485,18 @@ describe('error handling', () => {
|
|||||||
render() {}
|
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(fn).toHaveBeenCalledWith(err, 'setup function')
|
||||||
expect(
|
expect(
|
||||||
`Unhandled error during execution of setup function`
|
`Unhandled error during execution of setup function`
|
||||||
).toHaveBeenWarned()
|
).toHaveBeenWarned()
|
||||||
expect(onError).toHaveBeenCalledWith(err)
|
expect(caughtError).toBe(err)
|
||||||
|
|
||||||
onError.mockRestore()
|
|
||||||
groupCollapsed.mockRestore()
|
groupCollapsed.mockRestore()
|
||||||
log.mockRestore()
|
log.mockRestore()
|
||||||
})
|
})
|
||||||
|
@ -134,25 +134,20 @@ export function handleError(
|
|||||||
logError(err, type, contextVNode)
|
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) {
|
function logError(err: unknown, type: ErrorTypes, contextVNode: VNode | null) {
|
||||||
// default behavior is crash in prod & test, recover in dev.
|
if (__DEV__) {
|
||||||
if (__DEV__ && (forceRecover || !__TEST__)) {
|
|
||||||
const info = ErrorTypeStrings[type]
|
const info = ErrorTypeStrings[type]
|
||||||
if (contextVNode) {
|
if (contextVNode) {
|
||||||
pushWarningContext(contextVNode)
|
pushWarningContext(contextVNode)
|
||||||
}
|
}
|
||||||
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`)
|
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`)
|
||||||
console.error(err)
|
|
||||||
if (contextVNode) {
|
if (contextVNode) {
|
||||||
popWarningContext()
|
popWarningContext()
|
||||||
}
|
}
|
||||||
} else {
|
// crash in dev so it's more noticeable
|
||||||
throw err
|
throw err
|
||||||
|
} else {
|
||||||
|
// recover in prod to reduce the impact on end-user
|
||||||
|
console.error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user