diff --git a/src/core/observer/watcher.js b/src/core/observer/watcher.js index 5fbcdf347f2..e96533c8720 100644 --- a/src/core/observer/watcher.js +++ b/src/core/observer/watcher.js @@ -7,6 +7,7 @@ import { parsePath, _Set as Set, handleError, + invokeWithErrorHandling, noop } from '../util/index' @@ -191,11 +192,7 @@ export default class Watcher { const oldValue = this.value this.value = value if (this.user) { - try { - this.cb.call(this.vm, value, oldValue) - } catch (e) { - handleError(e, this.vm, `callback for watcher "${this.expression}"`) - } + invokeWithErrorHandling(this.cb, this.vm, [value, oldValue], this.vm, ("callback for watcher \"" + (this.expression) + "\"")) } else { this.cb.call(this.vm, value, oldValue) } diff --git a/test/unit/features/error-handling.spec.js b/test/unit/features/error-handling.spec.js index 7d0eaa512ab..7b0d91db025 100644 --- a/test/unit/features/error-handling.spec.js +++ b/test/unit/features/error-handling.spec.js @@ -138,6 +138,16 @@ describe('Error handling', () => { }).then(done) }) + it('should recover from errors in user watcher from promise error', done => { + const vm = createTestInstance(components.userWatcherPromise) + vm.n++ + setTimeout(() => { + expect(`Error in callback for watcher "n" (Promise/async)`).toHaveBeenWarned() + expect(`Error: userWatcherPromise error`).toHaveBeenWarned() + assertBothInstancesActive(vm).then(done) + }) + }) + it('should recover from errors in user immediate watcher callback', done => { const vm = createTestInstance(components.userImmediateWatcherCallback) waitForUpdate(() => { @@ -344,6 +354,18 @@ function createErrorTestComponents () { } } + components.userWatcherPromise = { + props: ['n'], + watch: { + n () { + return new Promise((resolve, reject) => reject(new Error('userWatcherPromise error'))) + } + }, + render (h) { + return h('div', this.n) + } + } + components.userImmediateWatcherCallback = { props: ['n'], watch: {