Skip to content

Commit b00868c

Browse files
committed
refactor: extract async error handling logic
1 parent 35edc1c commit b00868c

File tree

5 files changed

+34
-41
lines changed

5 files changed

+34
-41
lines changed

Diff for: src/core/instance/events.js

+3-8
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import {
44
tip,
55
toArray,
66
hyphenate,
7-
handleError,
87
formatComponentName,
9-
handlePromiseError
8+
invokeWithErrorHandling
109
} from '../util/index'
1110
import { updateListeners } from '../vdom/helpers/index'
1211

@@ -134,13 +133,9 @@ export function eventsMixin (Vue: Class<Component>) {
134133
if (cbs) {
135134
cbs = cbs.length > 1 ? toArray(cbs) : cbs
136135
const args = toArray(arguments, 1)
136+
const info = `event handler for "${event}"`
137137
for (let i = 0, l = cbs.length; i < l; i++) {
138-
try {
139-
const cbResult = cbs[i].apply(vm, args)
140-
handlePromiseError(cbResult, vm, `event handler for "${event}"`)
141-
} catch (e) {
142-
handleError(e, vm, `event handler for "${event}"`)
143-
}
138+
invokeWithErrorHandling(cbs[i], vm, args, vm, info)
144139
}
145140
}
146141
return vm

Diff for: src/core/instance/lifecycle.js

+3-8
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ import {
1313
warn,
1414
noop,
1515
remove,
16-
handleError,
1716
emptyObject,
1817
validateProp,
19-
handlePromiseError
18+
invokeWithErrorHandling
2019
} from '../util/index'
2120

2221
export let activeInstance: any = null
@@ -324,14 +323,10 @@ export function callHook (vm: Component, hook: string) {
324323
// #7573 disable dep collection when invoking lifecycle hooks
325324
pushTarget()
326325
const handlers = vm.$options[hook]
326+
const info = `${hook} hook`
327327
if (handlers) {
328328
for (let i = 0, j = handlers.length; i < j; i++) {
329-
try {
330-
const fnResult = handlers[i].call(vm)
331-
handlePromiseError(fnResult, vm, `${hook} hook`)
332-
} catch (e) {
333-
handleError(e, vm, `${hook} hook`)
334-
}
329+
invokeWithErrorHandling(handlers[i], vm, null, vm, info)
335330
}
336331
}
337332
if (vm._hasHookEvent) {

Diff for: src/core/util/error.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,23 @@ export function handleError (err: Error, vm: any, info: string) {
2525
globalHandleError(err, vm, info)
2626
}
2727

28-
export function handlePromiseError (value: any, vm: any, info: string) {
29-
// if value is promise, handle it (a promise must have a then function)
30-
if (isPromise(value)) {
31-
value.catch(e => handleError(e, vm, info))
28+
export function invokeWithErrorHandling (
29+
handler: Function,
30+
context: any,
31+
args: null | any[],
32+
vm: any,
33+
info: string
34+
) {
35+
let res
36+
try {
37+
res = args ? handler.apply(context, args) : handler.call(context)
38+
if (isPromise(res)) {
39+
res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
40+
}
41+
} catch (e) {
42+
handleError(e, vm, info)
3243
}
44+
return res
3345
}
3446

3547
function globalHandleError (err, vm, info) {

Diff for: src/core/vdom/helpers/update-listeners.js

+6-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/* @flow */
22

3-
import { warn, handleError, handlePromiseError } from 'core/util/index'
3+
import {
4+
warn,
5+
invokeWithErrorHandling
6+
} from 'core/util/index'
47
import {
58
cached,
69
isUndef,
@@ -36,23 +39,11 @@ export function createFnInvoker (fns: Function | Array<Function>, vm: ?Component
3639
if (Array.isArray(fns)) {
3740
const cloned = fns.slice()
3841
for (let i = 0; i < cloned.length; i++) {
39-
try {
40-
const result = cloned[i].apply(null, arguments)
41-
handlePromiseError(result, vm, 'v-on async')
42-
} catch (e) {
43-
handleError(e, vm, 'v-on')
44-
}
42+
invokeWithErrorHandling(cloned[i], null, arguments, vm, `v-on handler`)
4543
}
4644
} else {
4745
// return handler return value for single handlers
48-
let result
49-
try {
50-
result = fns.apply(null, arguments)
51-
handlePromiseError(result, vm, 'v-on async')
52-
} catch (e) {
53-
handleError(e, vm, 'v-on')
54-
}
55-
return result
46+
return invokeWithErrorHandling(fns, null, arguments, vm, `v-on handler`)
5647
}
5748
}
5849
invoker.fns = fns

Diff for: test/unit/features/error-handling.spec.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('Error handling', () => {
3333
it(`should recover from promise errors in ${type}`, done => {
3434
createTestInstance(components[`${type}Async`])
3535
waitForUpdate(() => {
36-
expect(`Error in ${description}`).toHaveBeenWarned()
36+
expect(`Error in ${description} (Promise/async)`).toHaveBeenWarned()
3737
expect(`Error: ${type}`).toHaveBeenWarned()
3838
}).then(done)
3939
})
@@ -70,7 +70,7 @@ describe('Error handling', () => {
7070
it(`should recover from promise errors in ${type} hook`, done => {
7171
const vm = createTestInstance(components[`${type}Async`])
7272
assertBothInstancesActive(vm).then(() => {
73-
expect(`Error in ${description}`).toHaveBeenWarned()
73+
expect(`Error in ${description} (Promise/async)`).toHaveBeenWarned()
7474
expect(`Error: ${type}`).toHaveBeenWarned()
7575
}).then(done)
7676
})
@@ -101,7 +101,7 @@ describe('Error handling', () => {
101101
const vm = createTestInstance(components[`${type}Async`])
102102
vm.ok = false
103103
setTimeout(() => {
104-
expect(`Error in ${description}`).toHaveBeenWarned()
104+
expect(`Error in ${description} (Promise/async)`).toHaveBeenWarned()
105105
expect(`Error: ${type}`).toHaveBeenWarned()
106106
assertRootInstanceActive(vm).then(done)
107107
})
@@ -211,7 +211,7 @@ describe('Error handling', () => {
211211
}).$mount()
212212
document.body.appendChild(vm.$el)
213213
triggerEvent(vm.$el, 'click')
214-
expect('Error in v-on').toHaveBeenWarned()
214+
expect('Error in v-on handler').toHaveBeenWarned()
215215
expect('Error: v-on').toHaveBeenWarned()
216216
document.body.removeChild(vm.$el)
217217
})
@@ -226,8 +226,8 @@ describe('Error handling', () => {
226226
document.body.appendChild(vm.$el)
227227
triggerEvent(vm.$el, 'click')
228228
waitForUpdate(() => {
229-
expect('Error in v-on async').toHaveBeenWarned()
230-
expect('Error: v-on async').toHaveBeenWarned()
229+
expect('Error in v-on handler (Promise/async)').toHaveBeenWarned()
230+
expect('Error: v-on').toHaveBeenWarned()
231231
document.body.removeChild(vm.$el)
232232
}).then(done)
233233
})

0 commit comments

Comments
 (0)