mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-05 13:38:18 +08:00
refactor: extract async error handling logic
This commit is contained in:
parent
35edc1c1e2
commit
b00868c5cb
@ -4,9 +4,8 @@ import {
|
|||||||
tip,
|
tip,
|
||||||
toArray,
|
toArray,
|
||||||
hyphenate,
|
hyphenate,
|
||||||
handleError,
|
|
||||||
formatComponentName,
|
formatComponentName,
|
||||||
handlePromiseError
|
invokeWithErrorHandling
|
||||||
} from '../util/index'
|
} from '../util/index'
|
||||||
import { updateListeners } from '../vdom/helpers/index'
|
import { updateListeners } from '../vdom/helpers/index'
|
||||||
|
|
||||||
@ -134,13 +133,9 @@ export function eventsMixin (Vue: Class<Component>) {
|
|||||||
if (cbs) {
|
if (cbs) {
|
||||||
cbs = cbs.length > 1 ? toArray(cbs) : cbs
|
cbs = cbs.length > 1 ? toArray(cbs) : cbs
|
||||||
const args = toArray(arguments, 1)
|
const args = toArray(arguments, 1)
|
||||||
|
const info = `event handler for "${event}"`
|
||||||
for (let i = 0, l = cbs.length; i < l; i++) {
|
for (let i = 0, l = cbs.length; i < l; i++) {
|
||||||
try {
|
invokeWithErrorHandling(cbs[i], vm, args, vm, info)
|
||||||
const cbResult = cbs[i].apply(vm, args)
|
|
||||||
handlePromiseError(cbResult, vm, `event handler for "${event}"`)
|
|
||||||
} catch (e) {
|
|
||||||
handleError(e, vm, `event handler for "${event}"`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vm
|
return vm
|
||||||
|
@ -13,10 +13,9 @@ import {
|
|||||||
warn,
|
warn,
|
||||||
noop,
|
noop,
|
||||||
remove,
|
remove,
|
||||||
handleError,
|
|
||||||
emptyObject,
|
emptyObject,
|
||||||
validateProp,
|
validateProp,
|
||||||
handlePromiseError
|
invokeWithErrorHandling
|
||||||
} from '../util/index'
|
} from '../util/index'
|
||||||
|
|
||||||
export let activeInstance: any = null
|
export let activeInstance: any = null
|
||||||
@ -324,14 +323,10 @@ export function callHook (vm: Component, hook: string) {
|
|||||||
// #7573 disable dep collection when invoking lifecycle hooks
|
// #7573 disable dep collection when invoking lifecycle hooks
|
||||||
pushTarget()
|
pushTarget()
|
||||||
const handlers = vm.$options[hook]
|
const handlers = vm.$options[hook]
|
||||||
|
const info = `${hook} hook`
|
||||||
if (handlers) {
|
if (handlers) {
|
||||||
for (let i = 0, j = handlers.length; i < j; i++) {
|
for (let i = 0, j = handlers.length; i < j; i++) {
|
||||||
try {
|
invokeWithErrorHandling(handlers[i], vm, null, vm, info)
|
||||||
const fnResult = handlers[i].call(vm)
|
|
||||||
handlePromiseError(fnResult, vm, `${hook} hook`)
|
|
||||||
} catch (e) {
|
|
||||||
handleError(e, vm, `${hook} hook`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vm._hasHookEvent) {
|
if (vm._hasHookEvent) {
|
||||||
|
@ -25,11 +25,23 @@ export function handleError (err: Error, vm: any, info: string) {
|
|||||||
globalHandleError(err, vm, info)
|
globalHandleError(err, vm, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handlePromiseError (value: any, vm: any, info: string) {
|
export function invokeWithErrorHandling (
|
||||||
// if value is promise, handle it (a promise must have a then function)
|
handler: Function,
|
||||||
if (isPromise(value)) {
|
context: any,
|
||||||
value.catch(e => handleError(e, vm, info))
|
args: null | any[],
|
||||||
|
vm: any,
|
||||||
|
info: string
|
||||||
|
) {
|
||||||
|
let res
|
||||||
|
try {
|
||||||
|
res = args ? handler.apply(context, args) : handler.call(context)
|
||||||
|
if (isPromise(res)) {
|
||||||
|
res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
handleError(e, vm, info)
|
||||||
}
|
}
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
function globalHandleError (err, vm, info) {
|
function globalHandleError (err, vm, info) {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
import { warn, handleError, handlePromiseError } from 'core/util/index'
|
import {
|
||||||
|
warn,
|
||||||
|
invokeWithErrorHandling
|
||||||
|
} from 'core/util/index'
|
||||||
import {
|
import {
|
||||||
cached,
|
cached,
|
||||||
isUndef,
|
isUndef,
|
||||||
@ -36,23 +39,11 @@ export function createFnInvoker (fns: Function | Array<Function>, vm: ?Component
|
|||||||
if (Array.isArray(fns)) {
|
if (Array.isArray(fns)) {
|
||||||
const cloned = fns.slice()
|
const cloned = fns.slice()
|
||||||
for (let i = 0; i < cloned.length; i++) {
|
for (let i = 0; i < cloned.length; i++) {
|
||||||
try {
|
invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`)
|
||||||
const result = cloned[i].apply(null, arguments)
|
|
||||||
handlePromiseError(result, vm, 'v-on async')
|
|
||||||
} catch (e) {
|
|
||||||
handleError(e, vm, 'v-on')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// return handler return value for single handlers
|
// return handler return value for single handlers
|
||||||
let result
|
return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)
|
||||||
try {
|
|
||||||
result = fns.apply(null, arguments)
|
|
||||||
handlePromiseError(result, vm, 'v-on async')
|
|
||||||
} catch (e) {
|
|
||||||
handleError(e, vm, 'v-on')
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invoker.fns = fns
|
invoker.fns = fns
|
||||||
|
@ -33,7 +33,7 @@ describe('Error handling', () => {
|
|||||||
it(`should recover from promise errors in ${type}`, done => {
|
it(`should recover from promise errors in ${type}`, done => {
|
||||||
createTestInstance(components[`${type}Async`])
|
createTestInstance(components[`${type}Async`])
|
||||||
waitForUpdate(() => {
|
waitForUpdate(() => {
|
||||||
expect(`Error in ${description}`).toHaveBeenWarned()
|
expect(`Error in ${description} (Promise/async)`).toHaveBeenWarned()
|
||||||
expect(`Error: ${type}`).toHaveBeenWarned()
|
expect(`Error: ${type}`).toHaveBeenWarned()
|
||||||
}).then(done)
|
}).then(done)
|
||||||
})
|
})
|
||||||
@ -70,7 +70,7 @@ describe('Error handling', () => {
|
|||||||
it(`should recover from promise errors in ${type} hook`, done => {
|
it(`should recover from promise errors in ${type} hook`, done => {
|
||||||
const vm = createTestInstance(components[`${type}Async`])
|
const vm = createTestInstance(components[`${type}Async`])
|
||||||
assertBothInstancesActive(vm).then(() => {
|
assertBothInstancesActive(vm).then(() => {
|
||||||
expect(`Error in ${description}`).toHaveBeenWarned()
|
expect(`Error in ${description} (Promise/async)`).toHaveBeenWarned()
|
||||||
expect(`Error: ${type}`).toHaveBeenWarned()
|
expect(`Error: ${type}`).toHaveBeenWarned()
|
||||||
}).then(done)
|
}).then(done)
|
||||||
})
|
})
|
||||||
@ -101,7 +101,7 @@ describe('Error handling', () => {
|
|||||||
const vm = createTestInstance(components[`${type}Async`])
|
const vm = createTestInstance(components[`${type}Async`])
|
||||||
vm.ok = false
|
vm.ok = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(`Error in ${description}`).toHaveBeenWarned()
|
expect(`Error in ${description} (Promise/async)`).toHaveBeenWarned()
|
||||||
expect(`Error: ${type}`).toHaveBeenWarned()
|
expect(`Error: ${type}`).toHaveBeenWarned()
|
||||||
assertRootInstanceActive(vm).then(done)
|
assertRootInstanceActive(vm).then(done)
|
||||||
})
|
})
|
||||||
@ -211,7 +211,7 @@ describe('Error handling', () => {
|
|||||||
}).$mount()
|
}).$mount()
|
||||||
document.body.appendChild(vm.$el)
|
document.body.appendChild(vm.$el)
|
||||||
triggerEvent(vm.$el, 'click')
|
triggerEvent(vm.$el, 'click')
|
||||||
expect('Error in v-on').toHaveBeenWarned()
|
expect('Error in v-on handler').toHaveBeenWarned()
|
||||||
expect('Error: v-on').toHaveBeenWarned()
|
expect('Error: v-on').toHaveBeenWarned()
|
||||||
document.body.removeChild(vm.$el)
|
document.body.removeChild(vm.$el)
|
||||||
})
|
})
|
||||||
@ -226,8 +226,8 @@ describe('Error handling', () => {
|
|||||||
document.body.appendChild(vm.$el)
|
document.body.appendChild(vm.$el)
|
||||||
triggerEvent(vm.$el, 'click')
|
triggerEvent(vm.$el, 'click')
|
||||||
waitForUpdate(() => {
|
waitForUpdate(() => {
|
||||||
expect('Error in v-on async').toHaveBeenWarned()
|
expect('Error in v-on handler (Promise/async)').toHaveBeenWarned()
|
||||||
expect('Error: v-on async').toHaveBeenWarned()
|
expect('Error: v-on').toHaveBeenWarned()
|
||||||
document.body.removeChild(vm.$el)
|
document.body.removeChild(vm.$el)
|
||||||
}).then(done)
|
}).then(done)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user