diff options
| author | Igor Minar | 2013-08-21 22:57:48 -0700 |
|---|---|---|
| committer | Igor Minar | 2013-08-24 12:49:46 -0700 |
| commit | 5d9f42050a11015adbd5dc4dde73818919e93a99 (patch) | |
| tree | 0d9096b863ff8add148e8ad180816b1937c28ad3 | |
| parent | 80d0f98263786ef302ca7551c4515560a7c07195 (diff) | |
| download | angular.js-5d9f42050a11015adbd5dc4dde73818919e93a99.tar.bz2 | |
fix($q): reject should catch & forward exceptions thrown in errback
| -rw-r--r-- | src/ng/q.js | 7 | ||||
| -rw-r--r-- | test/ng/qSpec.js | 20 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/ng/q.js b/src/ng/q.js index cc39967c..6c4d3f5f 100644 --- a/src/ng/q.js +++ b/src/ng/q.js @@ -375,7 +375,12 @@ function qFactory(nextTick, exceptionHandler) { then: function(callback, errback) { var result = defer(); nextTick(function() { - result.resolve((isFunction(errback) ? errback : defaultErrback)(reason)); + try { + result.resolve((isFunction(errback) ? errback : defaultErrback)(reason)); + } catch(e) { + result.reject(e); + exceptionHandler(e); + } }); return result.promise; } diff --git a/test/ng/qSpec.js b/test/ng/qSpec.js index 7c949602..28be0405 100644 --- a/test/ng/qSpec.js +++ b/test/ng/qSpec.js @@ -950,6 +950,15 @@ describe('q', function() { syncResolve(deferred, rejectedPromise.then()); expect(log).toEqual(['error(rejected)->reject(rejected)']); }); + + + it('should catch exceptions thrown in errback and forward them to derived promises', function() { + var rejectedPromise = q.reject('rejected'); + rejectedPromise.then(null, error('Broken', 'catch me!', true)). + then(null, error('Affected')) + mockNextTick.flush(); + expect(log).toEqual(['errorBroken(rejected)->throw(catch me!)', 'errorAffected(catch me!)->reject(catch me!)']); + }); }); @@ -1460,7 +1469,7 @@ describe('q', function() { deferred = q.defer(); }); - + afterEach(function() { // Restore the original exception logging mode mockNextTick.logExceptions = originalLogExceptions; @@ -1468,6 +1477,15 @@ describe('q', function() { it('should still reject the promise, when exception is thrown in success handler, even if exceptionHandler rethrows', function() { + deferred.promise.then(function() { throw 'reject'; }).then(null, errorSpy); + deferred.resolve('resolve'); + mockNextTick.flush(); + expect(exceptionExceptionSpy).toHaveBeenCalled(); + expect(errorSpy).toHaveBeenCalled(); + }); + + + it('should still reject the promise, when exception is thrown in error handler, even if exceptionHandler rethrows', function() { deferred.promise.then(null, function() { throw 'reject again'; }).then(null, errorSpy); deferred.reject('reject'); mockNextTick.flush(); |
