Skip to content

Commit 3ae5cf2

Browse files
vdeturckheimMylesBorins
authored andcommitted
events: move domain handling from events to domain
Backport-PR-URL: #18487 PR-URL: #17403 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Andreas Madsen <[email protected]> Reviewed-By: Timothy Gu <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]>
1 parent 6b1a40e commit 3ae5cf2

File tree

2 files changed

+52
-47
lines changed

2 files changed

+52
-47
lines changed

lib/domain.js

+46-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ const EventEmitter = require('events');
3131
const errors = require('internal/errors');
3232
const { createHook } = require('async_hooks');
3333

34-
// communicate with events module, but don't require that
35-
// module to have to load this one, since this module has
36-
// a few side effects.
37-
EventEmitter.usingDomains = true;
38-
3934
// overwrite process.domain with a getter/setter that will allow for more
4035
// effective optimizations
4136
var _domain = [null];
@@ -387,3 +382,49 @@ Domain.prototype.bind = function(cb) {
387382

388383
return runBound;
389384
};
385+
386+
// Override EventEmitter methods to make it domain-aware.
387+
EventEmitter.usingDomains = true;
388+
389+
const eventInit = EventEmitter.init;
390+
EventEmitter.init = function() {
391+
this.domain = null;
392+
if (exports.active && !(this instanceof exports.Domain)) {
393+
this.domain = exports.active;
394+
}
395+
396+
return eventInit.call(this);
397+
};
398+
399+
const eventEmit = EventEmitter.prototype.emit;
400+
EventEmitter.prototype.emit = function emit(...args) {
401+
const domain = this.domain;
402+
if (domain === null || domain === undefined || this === process) {
403+
return eventEmit.apply(this, args);
404+
}
405+
406+
const type = args[0];
407+
// edge case: if there is a domain and an existing non error object is given,
408+
// it should not be errorized
409+
// see test/parallel/test-event-emitter-no-error-provided-to-error-event.js
410+
if (type === 'error' && args.length > 1 && args[1] &&
411+
!(args[1] instanceof Error)) {
412+
domain.emit('error', args[1]);
413+
return false;
414+
}
415+
416+
domain.enter();
417+
try {
418+
return eventEmit.apply(this, args);
419+
} catch (er) {
420+
if (typeof er === 'object' && er !== null) {
421+
er.domainEmitter = this;
422+
er.domain = domain;
423+
er.domainThrown = false;
424+
}
425+
domain.emit('error', er);
426+
return false;
427+
} finally {
428+
domain.exit();
429+
}
430+
};

lib/events.js

+6-42
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
'use strict';
2323

24-
var domain;
2524
var spliceOne;
2625

2726
function EventEmitter() {
@@ -32,9 +31,6 @@ module.exports = EventEmitter;
3231
// Backwards-compat with node 0.10.x
3332
EventEmitter.EventEmitter = EventEmitter;
3433

35-
EventEmitter.usingDomains = false;
36-
37-
EventEmitter.prototype.domain = undefined;
3834
EventEmitter.prototype._events = undefined;
3935
EventEmitter.prototype._eventsCount = 0;
4036
EventEmitter.prototype._maxListeners = undefined;
@@ -67,14 +63,6 @@ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
6763
});
6864

6965
EventEmitter.init = function() {
70-
this.domain = null;
71-
if (EventEmitter.usingDomains) {
72-
// if there is an active domain, then attach to it.
73-
domain = domain || require('domain');
74-
if (domain.active && !(this instanceof domain.Domain)) {
75-
this.domain = domain.active;
76-
}
77-
}
7866

7967
if (this._events === undefined ||
8068
this._events === Object.getPrototypeOf(this)._events) {
@@ -115,47 +103,26 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
115103
else if (!doError)
116104
return false;
117105

118-
const domain = this.domain;
119-
120106
// If there is no 'error' event listener then throw.
121107
if (doError) {
122108
let er;
123109
if (args.length > 0)
124110
er = args[0];
125-
if (domain !== null && domain !== undefined) {
126-
if (!er) {
127-
const errors = lazyErrors();
128-
er = new errors.Error('ERR_UNHANDLED_ERROR');
129-
}
130-
if (typeof er === 'object' && er !== null) {
131-
er.domainEmitter = this;
132-
er.domain = domain;
133-
er.domainThrown = false;
134-
}
135-
domain.emit('error', er);
136-
} else if (er instanceof Error) {
111+
if (er instanceof Error) {
137112
throw er; // Unhandled 'error' event
138-
} else {
139-
// At least give some kind of context to the user
140-
const errors = lazyErrors();
141-
const err = new errors.Error('ERR_UNHANDLED_ERROR', er);
142-
err.context = er;
143-
throw err;
144113
}
145-
return false;
114+
// At least give some kind of context to the user
115+
const errors = lazyErrors();
116+
const err = new errors.Error('ERR_UNHANDLED_ERROR', er);
117+
err.context = er;
118+
throw err;
146119
}
147120

148121
const handler = events[type];
149122

150123
if (handler === undefined)
151124
return false;
152125

153-
let needDomainExit = false;
154-
if (domain !== null && domain !== undefined && this !== process) {
155-
domain.enter();
156-
needDomainExit = true;
157-
}
158-
159126
if (typeof handler === 'function') {
160127
handler.apply(this, args);
161128
} else {
@@ -165,9 +132,6 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
165132
listeners[i].apply(this, args);
166133
}
167134

168-
if (needDomainExit)
169-
domain.exit();
170-
171135
return true;
172136
};
173137

0 commit comments

Comments
 (0)