From 1634467598992032206b55f45a25066ad974ce4b Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 19 Dec 2016 14:20:32 +0000 Subject: [PATCH 1/2] Add traceback to unhandled promise rejections --- src/ng/q.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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); + } } } } From e37c89cbf4f840c29301a0da9b128dc4fced12d4 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Mon, 19 Dec 2016 14:20:20 +0000 Subject: [PATCH 2/2] add tests --- test/ng/qSpec.js | 70 +++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/test/ng/qSpec.js b/test/ng/qSpec.js index 210a4d983f81..42d57fbb4d62 100644 --- a/test/ng/qSpec.js +++ b/test/ng/qSpec.js @@ -2167,45 +2167,53 @@ 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 fixtures = [ + { type: 'exception', value: new Error('Fail') }, + { type: 'plain value', value: 'foo' } + ]; + forEach(fixtures, function(fixture) { + var type = fixture.type; + var value = fixture.value; + it('should log an unhandled' + type + ' rejected promise', function() { + var defer = q.defer(); + defer.reject('foo'); + mockNextTick.flush(); + expect(exceptionHandlerStr()).toBe('Possibly unhandled rejection: foo'); + }); - 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('foo'); + expect(exceptionHandlerStr()).toBe(''); + }); - 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('foo'); + mockNextTick.flush(); + expect(exceptionHandlerStr()).toBe('Possibly unhandled rejection: foo'); + }); - 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('foo'); + mockNextTick.flush(); + expect(exceptionHandlerStr()).toBe(''); + }); - 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('foo')); + mockNextTick.flush(); + expect(exceptionHandlerStr()).toBe(''); + }); }); }); });