diff --git a/src/promise.js b/src/promise.js index 219ee1296..680e0c211 100644 --- a/src/promise.js +++ b/src/promise.js @@ -240,6 +240,7 @@ Promise.reject = Promise.rejected = function Promise$Reject(reason) { var trace = new Error(reason + ""); ret._setCarriedStackTrace(trace); } + ret._ensurePossibleRejectionHandled(); return ret; }; @@ -253,6 +254,7 @@ function Promise$_resolveFromSyncValue(value, caller) { this._cleanValues(); this._setRejected(); this._settledValue = value.e; + this._ensurePossibleRejectionHandled(); } else { var maybePromise = Promise._cast(value, caller, void 0); @@ -1120,7 +1122,9 @@ function Promise$_notifyUnhandledRejection() { this._unsetCarriedStackTrace(); reason = trace; } - CapturedTrace.possiblyUnhandledRejection(reason, this); + if (typeof CapturedTrace.possiblyUnhandledRejection === "function") { + CapturedTrace.possiblyUnhandledRejection(reason, this); + } } }; diff --git a/test/mocha/unhandled_rejections.js b/test/mocha/unhandled_rejections.js index af90b64d6..e31249e8c 100644 --- a/test/mocha/unhandled_rejections.js +++ b/test/mocha/unhandled_rejections.js @@ -31,6 +31,12 @@ function onUnhandledSucceed( done, testAgainst ) { }); } +function async(fn) { + return function() { + setTimeout(function(){fn()}, 13); + }; +} + function onDone(done) { return function() { Promise.onPossiblyUnhandledRejection(null); @@ -461,10 +467,84 @@ describe("Will not report rejections that are handled in time", function() { }, 13 ); }); +}); + +describe("immediate failures without .then", function(done) { + var err = new Error(''); + specify("Promise.reject", function(done) { + onUnhandledSucceed(done, function(e) { + return e === err; + }); + + Promise.reject(err); + }); + + specify("new Promise throw", function(done) { + onUnhandledSucceed(done, function(e) { + return e === err; + }); + + new Promise(function() { + throw err; + }); + }); + + specify("new Promise reject", function(done) { + onUnhandledSucceed(done, function(e) { + return e === err; + }); + + new Promise(function(_, r) { + r(err); + }); + }); + + specify("Promise.method", function(done) { + onUnhandledSucceed(done, function(e) { + return e === err; + }); + + Promise.method(function() { + throw err; + })(); + }); +}); + +describe("immediate failures with .then", function(done) { + var err = new Error(''); + specify("Promise.reject", function(done) { + onUnhandledFail(); + + Promise.reject(err).caught(async(done)); + }); + + specify("new Promise throw", function(done) { + onUnhandledFail(); + + new Promise(function() { + throw err; + }).caught(async(done)); + }); + specify("new Promise reject", function(done) { + onUnhandledFail(); + + new Promise(function(_, r) { + r(err); + }).caught(async(done)); + }); + specify("Promise.method", function(done) { + onUnhandledFail(); + + Promise.method(function() { + throw err; + })().caught(async(done)); + }); }); + + if (Promise.hasLongStackTraces()) { describe("Gives long stack traces for non-errors", function() {