Skip to content

Commit

Permalink
Fixes #963
Browse files Browse the repository at this point in the history
  • Loading branch information
petkaantonov committed Jan 23, 2016
1 parent 6bd757e commit 0bc9bcd
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 10 deletions.
22 changes: 14 additions & 8 deletions src/finally.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ var util = require("./util");
var CancellationError = Promise.CancellationError;
var errorObj = util.errorObj;

function PassThroughHandlerContext(promise, type, handler) {
this.promise = promise;
this.type = type;
this.handler = handler;
this.called = false;
this.cancelPromise = null;
}

function FinallyHandlerCancelReaction(finallyHandler) {
this.finallyHandler = finallyHandler;
}
Expand Down Expand Up @@ -76,13 +84,11 @@ function finallyHandler(reasonOrValue) {

Promise.prototype._passThrough = function(handler, type, success, fail) {
if (typeof handler !== "function") return this.then();
return this._then(success, fail, undefined, {
promise: this,
handler: handler,
called: false,
cancelPromise: null,
type: type
}, undefined);
return this._then(success,
fail,
undefined,
new PassThroughHandlerContext(this, type, handler),
undefined);
};

Promise.prototype.lastly =
Expand All @@ -97,5 +103,5 @@ Promise.prototype.tap = function (handler) {
return this._passThrough(handler, TAP_TYPE, finallyHandler);
};

return finallyHandler;
return PassThroughHandlerContext;
};
5 changes: 3 additions & 2 deletions src/promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ var Context = require("./context")(Promise);
var createContext = Context.create;
var debug = require("./debuggability")(Promise, Context);
var CapturedTrace = debug.CapturedTrace;
var finallyHandler = require("./finally")(Promise, tryConvertToPromise);
var PassThroughHandlerContext =
require("./finally")(Promise, tryConvertToPromise);
var catchFilter = require("./catch_filter")(NEXT_FILTER);
var nodebackForPromise = require("./nodeback");
var errorObj = util.errorObj;
Expand Down Expand Up @@ -562,7 +563,7 @@ Promise.prototype._settlePromise = function(promise, handler, receiver, value) {
if (BIT_FIELD_CHECK(IS_CANCELLED)) {
if (isPromise) promise._invokeInternalOnCancel();

if (handler === finallyHandler) {
if (receiver instanceof PassThroughHandlerContext) {
receiver.cancelPromise = promise;
if (tryCatch(handler).call(receiver, value) === errorObj) {
promise._reject(errorObj.e);
Expand Down
39 changes: 39 additions & 0 deletions test/mocha/cancel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2903,3 +2903,42 @@ describe("Multi-branch cancellation", function() {
});
});
});



if (testUtils.isNodeJS) {
describe("issues", function() {
specify("cancels the promise chain within a domain GH963", function() {
var called = 0;
var thens = 0;
var resolveChain;
var Domain = require("domain");
var domain = Domain.create();

domain.enter();

var root = new Promise(function(resolve, reject, onCancel) {
resolveChain = resolve;
onCancel(function() {
called++;
});
}).then(function() {
thens++;
}).then(function() {
thens++;
}).then(function() {
thens++;
}).lastly(function() {
called++;
});

root.cancel();
resolveChain();
return awaitLateQueue(function() {
assert.equal(0, thens);
assert.equal(2, called);
domain.exit();
});
});
});
}

0 comments on commit 0bc9bcd

Please sign in to comment.