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:
Evan You 2020-07-28 00:17:59 -04:00
parent 678364802d
commit 3cc768f9f2
2 changed files with 12 additions and 24 deletions

View File

@ -10,17 +10,8 @@ import {
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()
@ -470,8 +461,6 @@ describe('error handling', () => {
})
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')
@ -496,14 +485,18 @@ describe('error handling', () => {
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()
})

View File

@ -134,25 +134,20 @@ export function handleError(
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)
}
}