diff --git a/src/ng/q.js b/src/ng/q.js index 305626150d99..de396b2d7c02 100644 --- a/src/ng/q.js +++ b/src/ng/q.js @@ -381,7 +381,11 @@ function qFactory(nextTick, exceptionHandler, errorOnUnhandledRejections) { if (!toCheck.pur) { toCheck.pur = true; var errorMessage = 'Possibly unhandled rejection: ' + toDebugString(toCheck.value); - exceptionHandler(errorMessage); + if (toCheck.value instanceof Error) { + exceptionHandler(toCheck.value, errorMessage); + } else { + exceptionHandler(errorMessage); + } } } } diff --git a/test/ng/qSpec.js b/test/ng/qSpec.js index 210a4d983f81..f0bcd826b9a8 100644 --- a/test/ng/qSpec.js +++ b/test/ng/qSpec.js @@ -181,16 +181,14 @@ describe('q', function() { }; - function exceptionHandler(reason) { - exceptionHandlerCalls.push(reason); - } - - - function exceptionHandlerStr() { - return exceptionHandlerCalls.join('; '); + function exceptionHandler(exception, reason) { + if (typeof reason === 'undefined') { + exceptionHandlerCalls.push({ reason: exception }); + } else { + exceptionHandlerCalls.push({ reason: reason, exception: exception }); + } } - beforeEach(function() { q = qFactory(mockNextTick.nextTick, exceptionHandler, true); q_no_error = qFactory(mockNextTick.nextTick, exceptionHandler, false); @@ -2167,45 +2165,69 @@ describe('q', function() { describe('when exceptionHandler is called', function() { - it('should log an unhandled rejected promise', function() { - var defer = q.defer(); - defer.reject('foo'); - mockNextTick.flush(); - expect(exceptionHandlerStr()).toBe('Possibly unhandled rejection: foo'); - }); + var exceptionEg = new Error('Fail'); + var exceptionStr = toDebugString(exceptionEg); + var fixtures = [ + { + type: 'exception', + value: exceptionEg, + expected: { + exception: exceptionEg, + reason: 'Possibly unhandled rejection: ' + exceptionStr + } + }, + { + type: 'plain value', + value: 'foo', + expected: { + reason: 'Possibly unhandled rejection: foo' + } + } + ]; + forEach(fixtures, function(fixture) { + var type = fixture.type; + var value = fixture.value; + var expected = fixture.expected; + it('should log an unhandled' + type + ' rejected promise', function() { + var defer = q.defer(); + defer.reject(value); + mockNextTick.flush(); + expect(exceptionHandlerCalls).toEqual([expected]); + }); - it('should not log an unhandled rejected promise if disabled', function() { - var defer = q_no_error.defer(); - defer.reject('foo'); - expect(exceptionHandlerStr()).toBe(''); - }); + it('should not log an unhandled' + type + ' rejected promise if disabled', function() { + var defer = q_no_error.defer(); + defer.reject(value); + expect(exceptionHandlerCalls).toEqual([]); + }); - it('should log a handled rejected promise on a promise without rejection callbacks', function() { - var defer = q.defer(); - defer.promise.then(noop); - defer.reject('foo'); - mockNextTick.flush(); - expect(exceptionHandlerStr()).toBe('Possibly unhandled rejection: foo'); - }); + it('should log a handled' + type + ' rejected promise on a promise without rejection callbacks', function() { + var defer = q.defer(); + defer.promise.then(noop); + defer.reject(value); + mockNextTick.flush(); + expect(exceptionHandlerCalls).toEqual([expected]); + }); - it('should not log a handled rejected promise', function() { - var defer = q.defer(); - defer.promise.catch(noop); - defer.reject('foo'); - mockNextTick.flush(); - expect(exceptionHandlerStr()).toBe(''); - }); + it('should not log a handled' + type + 'rejected promise', function() { + var defer = q.defer(); + defer.promise.catch(noop); + defer.reject(value); + mockNextTick.flush(); + expect(exceptionHandlerCalls).toEqual([]); + }); - it('should not log a handled rejected promise that is handled in a future tick', function() { - var defer = q.defer(); - defer.promise.catch(noop); - defer.resolve(q.reject('foo')); - mockNextTick.flush(); - expect(exceptionHandlerStr()).toBe(''); + it('should not log a handled' + type + ' rejected promise that is handled in a future tick', function() { + var defer = q.defer(); + defer.promise.catch(noop); + defer.resolve(q.reject(value)); + mockNextTick.flush(); + expect(exceptionHandlerCalls).toEqual([]); + }); }); }); });