diff --git a/src/history/base.js b/src/history/base.js index 4bfa0722b..a070f27c6 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -77,7 +77,17 @@ export class History { onComplete?: Function, onAbort?: Function ) { - const route = this.router.match(location, this.current) + let route + try { + route = this.router.match(location, this.current) + } catch (e) { + this.errorCbs.forEach(cb => { + cb(e) + }) + // Exception should still be thrown + // https://github.com/vuejs/vue-router/issues/3201 + throw e + } this.confirmTransition( route, () => { diff --git a/test/unit/specs/error-handling.spec.js b/test/unit/specs/error-handling.spec.js index d0d6f6e1d..d8784aa5e 100644 --- a/test/unit/specs/error-handling.spec.js +++ b/test/unit/specs/error-handling.spec.js @@ -183,4 +183,33 @@ describe('error handling', () => { done() }) }) + + it('should trigger onError when an exception is thrown', done => { + const config = [{ + path: '/oldpath/:part', + redirect: (to) => { + if (to.ooopsmistake.part) { + return `/newpath/${to.params.part}` + } + return '/newpath/' + } + }] + + const router = new VueRouter({ + routes: config + }) + + const onError = jasmine.createSpy('onError') + router.onError(onError) + const pushCatch = jasmine.createSpy('pushCatch') + + router + .push('/oldpath/test') + .catch(pushCatch) + .finally(() => { + expect(pushCatch).toHaveBeenCalled() + expect(onError).toHaveBeenCalled() + done() + }) + }) })