Browse Source

fix: should not swallow user catch on rejected promise in methods

fix #9694
dev
Evan You 6 years ago
parent
commit
7186940143
  1. 7
      src/core/util/error.js
  2. 7
      test/unit/modules/util/error.spec.js

7
src/core/util/error.js

@ -43,10 +43,11 @@ export function invokeWithErrorHandling (
let res let res
try { try {
res = args ? handler.apply(context, args) : handler.call(context) res = args ? handler.apply(context, args) : handler.call(context)
if (res && !res._isVue && isPromise(res)) { if (res && !res._isVue && isPromise(res) && !res._handled) {
res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
// issue #9511 // issue #9511
// reassign to res to avoid catch triggering multiple times when nested calls // avoid catch triggering multiple times when nested calls
res = res.catch(e => handleError(e, vm, info + ` (Promise/async)`)) res._handled = true
} }
} catch (e) { } catch (e) {
handleError(e, vm, info) handleError(e, vm, info)

7
test/unit/modules/util/invoke-with-error-handling.spec.js → test/unit/modules/util/error.spec.js

@ -6,14 +6,17 @@ describe('invokeWithErrorHandling', () => {
it('should errorHandler call once when nested calls return rejected promise', done => { it('should errorHandler call once when nested calls return rejected promise', done => {
const originalHandler = Vue.config.errorHandler const originalHandler = Vue.config.errorHandler
const handler = Vue.config.errorHandler = jasmine.createSpy() const handler = Vue.config.errorHandler = jasmine.createSpy()
const userCatch = jasmine.createSpy()
const err = new Error('fake error')
invokeWithErrorHandling(() => { invokeWithErrorHandling(() => {
return invokeWithErrorHandling(() => { return invokeWithErrorHandling(() => {
return Promise.reject(new Error('fake error')) return Promise.reject(err)
}) })
}).then(() => { }).catch(userCatch).then(() => {
Vue.config.errorHandler = originalHandler Vue.config.errorHandler = originalHandler
expect(handler.calls.count()).toBe(1) expect(handler.calls.count()).toBe(1)
expect(userCatch).toHaveBeenCalledWith(err)
done() done()
}) })
}) })
Loading…
Cancel
Save