File tree Expand file tree Collapse file tree 2 files changed +37
-0
lines changed
Expand file tree Collapse file tree 2 files changed +37
-0
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,8 @@ import { inBrowser } from './env'
44import { isPromise } from 'shared/util'
55import { pushTarget , popTarget } from '../observer/dep'
66
7+ let isHandlingError = false
8+
79export function handleError ( err : Error , vm : any , info : string ) {
810 // Deactivate deps tracking while processing error handler to avoid possible infinite rendering.
911 // See: https://github.com/vuejs/vuex/issues/1505
@@ -55,14 +57,21 @@ export function invokeWithErrorHandling(
5557
5658function globalHandleError ( err , vm , info ) {
5759 if ( config . errorHandler ) {
60+ if ( isHandlingError ) {
61+ logError ( err , vm , info )
62+ return
63+ }
5864 try {
65+ isHandlingError = true
5966 return config . errorHandler . call ( null , err , vm , info )
6067 } catch ( e : any ) {
6168 // if the user intentionally throws the original error in the handler,
6269 // do not log it twice
6370 if ( e !== err ) {
6471 logError ( e , null , 'config.errorHandler' )
6572 }
73+ } finally {
74+ isHandlingError = false
6675 }
6776 }
6877 logError ( err , vm , info )
Original file line number Diff line number Diff line change @@ -216,6 +216,34 @@ describe('Error handling', () => {
216216 Vue . config . errorHandler = undefined
217217 } )
218218
219+ it ( 'should avoid recursive error handling when errorHandler triggers another error' , ( ) => {
220+ const originalHandler = Vue . config . errorHandler
221+ let handlerCalls = 0
222+ Vue . config . errorHandler = ( err , instance ) => {
223+ handlerCalls ++
224+ if ( handlerCalls === 1 && instance ) {
225+ instance . $emit ( 'boom' )
226+ }
227+ }
228+ new Vue ( {
229+ created ( ) {
230+ this . $on ( 'boom' , ( ) => {
231+ throw new Error ( 'error in boom' )
232+ } )
233+ } ,
234+ render ( h ) {
235+ throw new Error ( 'error in render' )
236+ } ,
237+ renderError ( h , err ) {
238+ return h ( 'div' , err . toString ( ) )
239+ }
240+ } ) . $mount ( )
241+ expect ( handlerCalls ) . toBe ( 1 )
242+ expect ( 'Error in event handler for "boom"' ) . toHaveBeenWarned ( )
243+ expect ( 'Error: error in boom' ) . toHaveBeenWarned ( )
244+ Vue . config . errorHandler = originalHandler
245+ } )
246+
219247 // event handlers that can throw errors or return rejected promise
220248 ; [
221249 [ 'single handler' , '<div v-on:click="bork"></div>' ] ,
You can’t perform that action at this time.
0 commit comments