diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index b04cf054..a91dfd6a 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -6237,8 +6237,11 @@ getJasmineRequireObj().QueueRunner = function(j$) { QueueRunner.prototype.execute = function() { var self = this; - this.handleFinalError = function(error) { - self.onException(error); + this.handleFinalError = function(message, source, lineno, colno, error) { + // Older browsers would send the error as the first parameter. HTML5 + // specifies the the five parameters above. The error instance should + // be preffered, otherwise the call stack would get lost. + self.onException(error || message); }; this.globalErrors.pushListener(this.handleFinalError); this.run(0); diff --git a/spec/core/GlobalErrorsSpec.js b/spec/core/GlobalErrorsSpec.js index 9ff19891..3880b041 100644 --- a/spec/core/GlobalErrorsSpec.js +++ b/spec/core/GlobalErrorsSpec.js @@ -12,6 +12,26 @@ describe('GlobalErrors', function() { expect(handler).toHaveBeenCalledWith('foo'); }); + it('calls the global error handler with all parameters', function() { + var fakeGlobal = { onerror: null }, + handler = jasmine.createSpy('errorHandler'), + errors = new jasmineUnderTest.GlobalErrors(fakeGlobal), + fooError = new Error('foo'); + + errors.install(); + errors.pushListener(handler); + + fakeGlobal.onerror(fooError.message, 'foo.js', 1, 1, fooError); + + expect(handler).toHaveBeenCalledWith( + fooError.message, + 'foo.js', + 1, + 1, + fooError + ); + }); + it('only calls the most recent handler', function() { var fakeGlobal = { onerror: null }, handler1 = jasmine.createSpy('errorHandler1'), diff --git a/spec/core/QueueRunnerSpec.js b/spec/core/QueueRunnerSpec.js index e0b4c23c..ac18b81d 100644 --- a/spec/core/QueueRunnerSpec.js +++ b/spec/core/QueueRunnerSpec.js @@ -514,6 +514,32 @@ describe('QueueRunner', function() { }); }); + it('passes the error instance to exception handlers in HTML browsers', function() { + var error = new Error('fake error'), + onExceptionCallback = jasmine.createSpy('on exception callback'), + queueRunner = new jasmineUnderTest.QueueRunner({ + onException: onExceptionCallback + }); + + queueRunner.execute(); + queueRunner.handleFinalError(error.message, 'fake.js', 1, 1, error); + + expect(onExceptionCallback).toHaveBeenCalledWith(error); + }); + + it('passes the first argument to exception handlers for compatibility', function() { + var error = new Error('fake error'), + onExceptionCallback = jasmine.createSpy('on exception callback'), + queueRunner = new jasmineUnderTest.QueueRunner({ + onException: onExceptionCallback + }); + + queueRunner.execute(); + queueRunner.handleFinalError(error.message); + + expect(onExceptionCallback).toHaveBeenCalledWith(error.message); + }); + it('calls exception handlers when an exception is thrown in a fn', function() { var queueableFn = { type: 'queueable', diff --git a/src/core/QueueRunner.js b/src/core/QueueRunner.js index 63bc60ba..28c1153f 100644 --- a/src/core/QueueRunner.js +++ b/src/core/QueueRunner.js @@ -49,8 +49,11 @@ getJasmineRequireObj().QueueRunner = function(j$) { QueueRunner.prototype.execute = function() { var self = this; - this.handleFinalError = function(error) { - self.onException(error); + this.handleFinalError = function(message, source, lineno, colno, error) { + // Older browsers would send the error as the first parameter. HTML5 + // specifies the the five parameters above. The error instance should + // be preffered, otherwise the call stack would get lost. + self.onException(error || message); }; this.globalErrors.pushListener(this.handleFinalError); this.run(0);