Skip to content

Instantly share code, notes, and snippets.

@misterdjules
Created January 7, 2016 01:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save misterdjules/8fc28539c3e095ee2e35 to your computer and use it in GitHub Desktop.
Save misterdjules/8fc28539c3e095ee2e35 to your computer and use it in GitHub Desktop.
diff --git a/lib/domain.js b/lib/domain.js
index 630d02e..dc7901c 100644
--- a/lib/domain.js
+++ b/lib/domain.js
@@ -65,11 +65,21 @@ Domain.prototype._errorHandler = function errorHandler(er) {
function emitError() {
var handled = self.emit('error', er);
- // Exit all domains on the stack. Uncaught exceptions end the
- // current tick and no domains should be left on the stack
- // between ticks.
- stack.length = 0;
- exports.active = process.domain = null;
+ var topLevelDomain = stack.pop();
+ // Unwind domains stack until we reach the boundary between
+ // domains entered from within a frame that has an external
+ // exception handler and domains entered outside of that
+ // external exception handler.
+ while (topLevelDomain && !topLevelDomain.externalBoundary) {
+ topLevelDomain.exit();
+ topLevelDomain = stack.pop();
+ }
+
+ if (stack.length > 0) {
+ exports.active = process.domain = stack[stack.length - 1];
+ } else {
+ exports.active = process.domain = null;
+ }
return handled;
}
@@ -145,12 +155,16 @@ Domain.prototype._errorHandler = function errorHandler(er) {
};
-Domain.prototype.enter = function() {
+Domain.prototype.enter = function(fromExternal) {
if (this._disposed) return;
// note that this might be a no-op, but we still need
// to push it onto the stack so that we can pop it later.
exports.active = process.domain = this;
+
+ if (fromExternal)
+ stack.push({externalBoundary: true});
+
stack.push(this);
_domain_flag[0] = stack.length;
};
diff --git a/src/node.cc b/src/node.cc
index e533a52..b5e6ea0 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1167,7 +1167,9 @@ Local<Value> MakeCallback(Environment* env,
if (has_domain) {
Local<Value> enter_v = domain->Get(env->enter_string());
if (enter_v->IsFunction()) {
- enter_v.As<Function>()->Call(domain, 0, nullptr);
+ Local<Value> enter_argv[1];
+ enter_argv[0] = True(env->isolate());
+ enter_v.As<Function>()->Call(domain, 1, enter_argv);
if (try_catch.HasCaught())
return Undefined(env->isolate());
}
diff --git a/test/addons/make-callback-recurse/test.js b/test/addons/make-callback-recurse/test.js
index bb7a2ef..8dceb3a 100644
--- a/test/addons/make-callback-recurse/test.js
+++ b/test/addons/make-callback-recurse/test.js
@@ -68,7 +68,7 @@ common.mustCall(function runner(arg) {
runner(3);
}), 10);
} else if (arg === 3) {
- //checkDomains();
+ checkDomains();
} else {
throw new Error('UNREACHABLE');
}
@@ -79,6 +79,9 @@ function checkDomains() {
const d1 = domain.create();
const d2 = domain.create();
+ d1.on('error', function() { process._rawDebug('d1 error') });
+ d2.on('error', function() { process._rawDebug('d2 error') });
+
d1.run(common.mustCall(function() {
makeCallback({domain:d2}, function() {
throw new Error('test d2');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment