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
try {
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
// reassign to res to avoid catch triggering multiple times when nested calls
res = res.catch(e => handleError(e, vm, info + ` (Promise/async)`))
// avoid catch triggering multiple times when nested calls
res._handled = true
}
} catch (e) {
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 => {
const originalHandler = Vue.config.errorHandler
const handler = Vue.config.errorHandler = jasmine.createSpy()
const userCatch = jasmine.createSpy()
const err = new Error('fake error')
invokeWithErrorHandling(() => {
return invokeWithErrorHandling(() => {
return Promise.reject(new Error('fake error'))
return Promise.reject(err)
})
}).then(() => {
}).catch(userCatch).then(() => {
Vue.config.errorHandler = originalHandler
expect(handler.calls.count()).toBe(1)
expect(userCatch).toHaveBeenCalledWith(err)
done()
})
})
Loading…
Cancel
Save