events: improve max listeners warning

This adds the constructor name of the event target to the emitted
warning. Right now it's difficult to identify where the leak is
actually coming from and having some further information about the
source will likely help to identify the source.

PR-URL: https://github.com/nodejs/node/pull/27694
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Ruben Bridgewater 2019-05-14 16:45:15 +02:00 committed by Daniel Bevenius
parent 776e0000bc
commit 9375088bd3
4 changed files with 20 additions and 6 deletions

View File

@ -31,6 +31,10 @@ const {
ERR_UNHANDLED_ERROR ERR_UNHANDLED_ERROR
} = require('internal/errors').codes; } = require('internal/errors').codes;
const {
inspect
} = require('internal/util/inspect');
function EventEmitter() { function EventEmitter() {
EventEmitter.init.call(this); EventEmitter.init.call(this);
} }
@ -253,8 +257,8 @@ function _addListener(target, type, listener, prepend) {
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
const w = new Error('Possible EventEmitter memory leak detected. ' + const w = new Error('Possible EventEmitter memory leak detected. ' +
`${existing.length} ${String(type)} listeners ` + `${existing.length} ${String(type)} listeners ` +
'added. Use emitter.setMaxListeners() to ' + `added to ${inspect(target, { depth: -1 })}. Use ` +
'increase limit'); 'emitter.setMaxListeners() to increase limit');
w.name = 'MaxListenersExceededWarning'; w.name = 'MaxListenersExceededWarning';
w.emitter = target; w.emitter = target;
w.type = type; w.type = type;

View File

@ -15,7 +15,8 @@ process.on('warning', common.mustCall((warning) => {
assert.strictEqual(warning.emitter, e); assert.strictEqual(warning.emitter, e);
assert.strictEqual(warning.count, 2); assert.strictEqual(warning.count, 2);
assert.strictEqual(warning.type, null); assert.strictEqual(warning.type, null);
assert.ok(warning.message.includes('2 null listeners added.')); assert.ok(warning.message.includes(
'2 null listeners added to [EventEmitter].'));
})); }));
e.on(null, () => {}); e.on(null, () => {});

View File

@ -17,7 +17,8 @@ process.on('warning', common.mustCall((warning) => {
assert.strictEqual(warning.emitter, e); assert.strictEqual(warning.emitter, e);
assert.strictEqual(warning.count, 2); assert.strictEqual(warning.count, 2);
assert.strictEqual(warning.type, symbol); assert.strictEqual(warning.type, symbol);
assert.ok(warning.message.includes('2 Symbol(symbol) listeners added.')); assert.ok(warning.message.includes(
'2 Symbol(symbol) listeners added to [EventEmitter].'));
})); }));
e.on(symbol, () => {}); e.on(symbol, () => {});

View File

@ -6,7 +6,14 @@ const common = require('../common');
const events = require('events'); const events = require('events');
const assert = require('assert'); const assert = require('assert');
const e = new events.EventEmitter(); class FakeInput extends events.EventEmitter {
resume() {}
pause() {}
write() {}
end() {}
}
const e = new FakeInput();
e.setMaxListeners(1); e.setMaxListeners(1);
process.on('warning', common.mustCall((warning) => { process.on('warning', common.mustCall((warning) => {
@ -15,7 +22,8 @@ process.on('warning', common.mustCall((warning) => {
assert.strictEqual(warning.emitter, e); assert.strictEqual(warning.emitter, e);
assert.strictEqual(warning.count, 2); assert.strictEqual(warning.count, 2);
assert.strictEqual(warning.type, 'event-type'); assert.strictEqual(warning.type, 'event-type');
assert.ok(warning.message.includes('2 event-type listeners added.')); assert.ok(warning.message.includes(
'2 event-type listeners added to [FakeInput].'));
})); }));
e.on('event-type', () => {}); e.on('event-type', () => {});