Skip to content

Commit 4b6913c

Browse files
committed
handle errors in nextTick (close vuejs#5277)
1 parent 4dff99d commit 4b6913c

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

src/core/util/env.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* globals MutationObserver */
33

44
import { noop } from 'shared/util'
5+
import { handleError } from './error'
56

67
// can we use __proto__?
78
export const hasProto = '__proto__' in {}
@@ -123,15 +124,22 @@ export const nextTick = (function () {
123124
return function queueNextTick (cb?: Function, ctx?: Object) {
124125
let _resolve
125126
callbacks.push(() => {
126-
if (cb) cb.call(ctx)
127-
if (_resolve) _resolve(ctx)
127+
if (cb) {
128+
try {
129+
cb.call(ctx)
130+
} catch (e) {
131+
handleError(e, ctx, 'nextTick')
132+
}
133+
} else if (_resolve) {
134+
_resolve(ctx)
135+
}
128136
})
129137
if (!pending) {
130138
pending = true
131139
timerFunc()
132140
}
133141
if (!cb && typeof Promise !== 'undefined') {
134-
return new Promise(resolve => {
142+
return new Promise((resolve, reject) => {
135143
_resolve = resolve
136144
})
137145
}

test/unit/features/error-handling.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,25 @@ describe('Error handling', () => {
106106
}).then(done)
107107
})
108108

109+
it('should capture and recover from nextTick errors', done => {
110+
const err1 = new Error('nextTick')
111+
const err2 = new Error('nextTick2')
112+
const spy = Vue.config.errorHandler = jasmine.createSpy('errorHandler')
113+
Vue.nextTick(() => { throw err1 })
114+
Vue.nextTick(() => {
115+
expect(spy).toHaveBeenCalledWith(err1, undefined, 'nextTick')
116+
117+
const vm = new Vue()
118+
vm.$nextTick(() => { throw err2 })
119+
Vue.nextTick(() => {
120+
// should be called with correct instance info
121+
expect(spy).toHaveBeenCalledWith(err2, vm, 'nextTick')
122+
Vue.config.errorHandler = null
123+
done()
124+
})
125+
})
126+
})
127+
109128
it('properly format component names', () => {
110129
const vm = new Vue()
111130
expect(formatComponentName(vm)).toBe('<Root>')

0 commit comments

Comments
 (0)