From 2b5c83af6d8b15510424af4877d58c261ea02e16 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 3 Oct 2017 18:23:43 -0400 Subject: [PATCH] fix: handle errors in errorHandler close #6714 --- src/core/util/error.js | 28 +++++++++++++++-------- test/unit/features/error-handling.spec.js | 20 +++++++++++++++- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/core/util/error.js b/src/core/util/error.js index 69d44429467..b961986a585 100644 --- a/src/core/util/error.js +++ b/src/core/util/error.js @@ -6,16 +6,24 @@ import { inBrowser } from './env' export function handleError (err: Error, vm: any, info: string) { if (config.errorHandler) { - config.errorHandler.call(null, err, vm, info) - } else { - if (process.env.NODE_ENV !== 'production') { - warn(`Error in ${info}: "${err.toString()}"`, vm) - } - /* istanbul ignore else */ - if (inBrowser && typeof console !== 'undefined') { - console.error(err) - } else { - throw err + try { + config.errorHandler.call(null, err, vm, info) + return + } catch (e) { + logError(e, null, 'errorHandler') } } + logError(err, vm, info) +} + +function logError (err, vm, info) { + if (process.env.NODE_ENV !== 'production') { + warn(`Error in ${info}: "${err.toString()}"`, vm) + } + /* istanbul ignore else */ + if (inBrowser && typeof console !== 'undefined') { + console.error(err) + } else { + throw err + } } diff --git a/test/unit/features/error-handling.spec.js b/test/unit/features/error-handling.spec.js index 033f9a3b7d5..5bf05fdb120 100644 --- a/test/unit/features/error-handling.spec.js +++ b/test/unit/features/error-handling.spec.js @@ -92,7 +92,7 @@ describe('Error handling', () => { }).then(done) }) - it('config.errorHandler should capture errors', done => { + it('config.errorHandler should capture render errors', done => { const spy = Vue.config.errorHandler = jasmine.createSpy('errorHandler') const vm = createTestInstance(components.render) @@ -124,6 +124,24 @@ describe('Error handling', () => { }) }) }) + + it('should recover from errors thrown in errorHandler itself', () => { + Vue.config.errorHandler = () => { + throw new Error('error in errorHandler ¯\\_(ツ)_/¯') + } + const vm = new Vue({ + render (h) { + throw new Error('error in render') + }, + renderError (h, err) { + return h('div', err.toString()) + } + }).$mount() + expect('error in errorHandler').toHaveBeenWarned() + expect('error in render').toHaveBeenWarned() + expect(vm.$el.textContent).toContain('error in render') + Vue.config.errorHandler = null + }) }) function createErrorTestComponents () {