Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit 467e00e

Browse files
committed
domain: move error handling directly into instance
Instead of doing all the domain handling in core, allow the domain to set an error handler that'll take care of it all. This way the domain error handling can be abstracted enough for any user to use it.
1 parent 7555227 commit 467e00e

File tree

2 files changed

+61
-52
lines changed

2 files changed

+61
-52
lines changed

lib/domain.js

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ process._setupDomainUse(_domain, _domain_flag);
5454

5555
exports.Domain = Domain;
5656

57-
exports.create = exports.createDomain = function(cb) {
58-
return new Domain(cb);
57+
exports.create = exports.createDomain = function() {
58+
return new Domain();
5959
};
6060

6161
// it's possible to enter one domain while already inside
@@ -74,6 +74,58 @@ function Domain() {
7474
this.members = [];
7575
}
7676

77+
Domain.prototype.members = undefined;
78+
Domain.prototype._disposed = undefined;
79+
80+
// Called by process._fatalException in case an error was thrown.
81+
Domain.prototype._errorHandler = function errorHandler(er) {
82+
var caught = false;
83+
// ignore errors on disposed domains.
84+
//
85+
// XXX This is a bit stupid. We should probably get rid of
86+
// domain.dispose() altogether. It's almost always a terrible
87+
// idea. --isaacs
88+
if (this._disposed)
89+
return true;
90+
91+
er.domain = this;
92+
er.domainThrown = true;
93+
// wrap this in a try/catch so we don't get infinite throwing
94+
try {
95+
// One of three things will happen here.
96+
//
97+
// 1. There is a handler, caught = true
98+
// 2. There is no handler, caught = false
99+
// 3. It throws, caught = false
100+
//
101+
// If caught is false after this, then there's no need to exit()
102+
// the domain, because we're going to crash the process anyway.
103+
caught = this.emit('error', er);
104+
105+
// Exit all domains on the stack. Uncaught exceptions end the
106+
// current tick and no domains should be left on the stack
107+
// between ticks.
108+
stack.length = 0;
109+
exports.active = process.domain = null;
110+
} catch (er2) {
111+
// The domain error handler threw! oh no!
112+
// See if another domain can catch THIS error,
113+
// or else crash on the original one.
114+
// If the user already exited it, then don't double-exit.
115+
if (this === exports.active) {
116+
stack.pop();
117+
}
118+
if (stack.length) {
119+
exports.active = process.domain = stack[stack.length - 1];
120+
caught = process._fatalException(er2);
121+
} else {
122+
caught = false;
123+
}
124+
return caught;
125+
}
126+
return caught;
127+
};
128+
77129
Domain.prototype.enter = function() {
78130
if (this._disposed) return;
79131

src/node.js

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -216,60 +216,15 @@
216216
};
217217

218218
startup.processFatal = function() {
219-
// call into the active domain, or emit uncaughtException,
220-
// and exit if there are no listeners.
221219
process._fatalException = function(er) {
222220
var caught = false;
223-
if (process.domain) {
224-
var domain = process.domain;
225-
var domainModule = NativeModule.require('domain');
226-
var domainStack = domainModule._stack;
227221

228-
// ignore errors on disposed domains.
229-
//
230-
// XXX This is a bit stupid. We should probably get rid of
231-
// domain.dispose() altogether. It's almost always a terrible
232-
// idea. --isaacs
233-
if (domain._disposed)
234-
return true;
235-
236-
er.domain = domain;
237-
er.domainThrown = true;
238-
// wrap this in a try/catch so we don't get infinite throwing
239-
try {
240-
// One of three things will happen here.
241-
//
242-
// 1. There is a handler, caught = true
243-
// 2. There is no handler, caught = false
244-
// 3. It throws, caught = false
245-
//
246-
// If caught is false after this, then there's no need to exit()
247-
// the domain, because we're going to crash the process anyway.
248-
caught = domain.emit('error', er);
249-
250-
// Exit all domains on the stack. Uncaught exceptions end the
251-
// current tick and no domains should be left on the stack
252-
// between ticks.
253-
var domainModule = NativeModule.require('domain');
254-
domainStack.length = 0;
255-
domainModule.active = process.domain = null;
256-
} catch (er2) {
257-
// The domain error handler threw! oh no!
258-
// See if another domain can catch THIS error,
259-
// or else crash on the original one.
260-
// If the user already exited it, then don't double-exit.
261-
if (domain === domainModule.active)
262-
domainStack.pop();
263-
if (domainStack.length) {
264-
var parentDomain = domainStack[domainStack.length - 1];
265-
process.domain = domainModule.active = parentDomain;
266-
caught = process._fatalException(er2);
267-
} else
268-
caught = false;
269-
}
222+
if (process.domain && process.domain._errorHandler) {
223+
caught = process.domain._errorHandler(er);
270224
} else {
271225
caught = process.emit('uncaughtException', er);
272226
}
227+
273228
// if someone handled it, then great. otherwise, die in C++ land
274229
// since that means that we'll exit the process, emit the 'exit' event
275230
if (!caught) {
@@ -281,10 +236,12 @@
281236
} catch (er) {
282237
// nothing to be done about it at this point.
283238
}
284-
}
239+
285240
// if we handled an error, then make sure any ticks get processed
286-
if (caught)
241+
} else {
287242
setImmediate(process._tickCallback);
243+
}
244+
288245
return caught;
289246
};
290247
};

0 commit comments

Comments
 (0)