diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 94b74490..37135702 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -4559,34 +4559,56 @@ getJasmineRequireObj().GlobalErrors = function(j$) { class NodeAdapter { #global; #dispatch; + #originalHandlers; + #jasmineHandlers; constructor(global, dispatch) { this.#global = global; this.#dispatch = dispatch; + this.#jasmineHandlers = {}; + this.#originalHandlers = {}; + this.onError = this.onError.bind(this); this.onUnhandledRejection = this.onUnhandledRejection.bind(this); } install() { - this.#global.process.on('uncaughtException', this.onError); - this.#global.process.on('unhandledRejection', this.onUnhandledRejection); - this.#global.process.on( + this.#installHandler('uncaughtException', this.onError); + this.#installHandler('unhandledRejection', this.onUnhandledRejection); + this.#installHandler( 'rejectionHandled', this.#dispatch.onRejectionHandled ); } uninstall() { - this.#global.process.removeListener('uncaughtException', this.onError); - this.#global.process.removeListener( - 'unhandledRejection', - this.onUnhandledRejection - ); - this.#global.process.removeListener( - 'rejectionHandled', - this.#dispatch.onRejectionHandled + const errorTypes = Object.keys(this.#originalHandlers); + for (const errorType of errorTypes) { + this.#global.process.removeListener( + errorType, + this.#jasmineHandlers[errorType] + ); + + for (let i = 0; i < this.#originalHandlers[errorType].length; i++) { + this.#global.process.on( + errorType, + this.#originalHandlers[errorType][i] + ); + } + delete this.#originalHandlers[errorType]; + delete this.#jasmineHandlers[errorType]; + } + } + + #installHandler(errorType, handler) { + this.#originalHandlers[errorType] = this.#global.process.listeners( + errorType ); + this.#jasmineHandlers[errorType] = handler; + + this.#global.process.removeAllListeners(errorType); + this.#global.process.on(errorType, handler); } #augmentError(error, isUnhandledRejection) { diff --git a/spec/core/GlobalErrorsSpec.js b/spec/core/GlobalErrorsSpec.js index 799814f9..959bb340 100644 --- a/spec/core/GlobalErrorsSpec.js +++ b/spec/core/GlobalErrorsSpec.js @@ -142,9 +142,11 @@ describe('GlobalErrors', function() { errors.install(); expect(globals.listeners.uncaughtException).toEqual([ - originalHandler, jasmine.any(Function) ]); + expect(globals.listeners.uncaughtException).not.toEqual([ + originalHandler() + ]); errors.pushListener(handler); @@ -173,9 +175,11 @@ describe('GlobalErrors', function() { errors.install(); expect(globals.listeners.unhandledRejection).toEqual([ - originalHandler, jasmine.any(Function) ]); + expect(globals.listeners.unhandledRejection).not.toEqual([ + originalHandler() + ]); errors.pushListener(handler); @@ -253,9 +257,11 @@ describe('GlobalErrors', function() { errors.install(); expect(globals.listeners.rejectionHandled).toEqual([ - originalHandler, jasmine.any(Function) ]); + expect(globals.listeners.rejectionHandled).not.toEqual([ + originalHandler + ]); errors.uninstall(); expect(globals.listeners.rejectionHandled).toEqual([originalHandler]); diff --git a/src/core/GlobalErrors.js b/src/core/GlobalErrors.js index 7fd5d3b1..27af0128 100644 --- a/src/core/GlobalErrors.js +++ b/src/core/GlobalErrors.js @@ -191,34 +191,56 @@ getJasmineRequireObj().GlobalErrors = function(j$) { class NodeAdapter { #global; #dispatch; + #originalHandlers; + #jasmineHandlers; constructor(global, dispatch) { this.#global = global; this.#dispatch = dispatch; + this.#jasmineHandlers = {}; + this.#originalHandlers = {}; + this.onError = this.onError.bind(this); this.onUnhandledRejection = this.onUnhandledRejection.bind(this); } install() { - this.#global.process.on('uncaughtException', this.onError); - this.#global.process.on('unhandledRejection', this.onUnhandledRejection); - this.#global.process.on( + this.#installHandler('uncaughtException', this.onError); + this.#installHandler('unhandledRejection', this.onUnhandledRejection); + this.#installHandler( 'rejectionHandled', this.#dispatch.onRejectionHandled ); } uninstall() { - this.#global.process.removeListener('uncaughtException', this.onError); - this.#global.process.removeListener( - 'unhandledRejection', - this.onUnhandledRejection - ); - this.#global.process.removeListener( - 'rejectionHandled', - this.#dispatch.onRejectionHandled + const errorTypes = Object.keys(this.#originalHandlers); + for (const errorType of errorTypes) { + this.#global.process.removeListener( + errorType, + this.#jasmineHandlers[errorType] + ); + + for (let i = 0; i < this.#originalHandlers[errorType].length; i++) { + this.#global.process.on( + errorType, + this.#originalHandlers[errorType][i] + ); + } + delete this.#originalHandlers[errorType]; + delete this.#jasmineHandlers[errorType]; + } + } + + #installHandler(errorType, handler) { + this.#originalHandlers[errorType] = this.#global.process.listeners( + errorType ); + this.#jasmineHandlers[errorType] = handler; + + this.#global.process.removeAllListeners(errorType); + this.#global.process.on(errorType, handler); } #augmentError(error, isUnhandledRejection) {