Skip to content

Commit 932c824

Browse files
committed
events: make memory leak warning more accessible
This makes the famous `EventEmitter memory leak` warnings occurring when the listener count for a given event exceeds a specified number more programatically accessible, by giving them properties referring to the event emitter instance and the event itself. This can be useful for debugging the origins of such a warning when the stack itself doesn’t reveal enough information about the event emitter instance itself, e.g. when manual inspection of the already-registered listeners is expected to be useful. PR-URL: #8298 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 1b8accf commit 932c824

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

doc/api/events.md

+10
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,14 @@ emitter.once('event', () => {
278278
});
279279
```
280280

281+
The [`--trace-warnings`][] command line flag can be used to display the
282+
stack trace for such warnings.
283+
284+
The emitted warning can be inspected with [`process.on('warning')`][] and will
285+
have the additional `emitter`, `type` and `count` properties, referring to
286+
the event emitter instance, the event’s name and the number of attached
287+
listeners, respectively.
288+
281289
### emitter.addListener(eventName, listener)
282290
<!-- YAML
283291
added: v0.1.26
@@ -562,4 +570,6 @@ Returns a reference to the `EventEmitter`, so that calls can be chained.
562570
[`emitter.listenerCount()`]: #events_emitter_listenercount_eventname
563571
[`domain`]: domain.html
564572
[`process` object's `uncaughtException` event]: process.html#process_event_uncaughtexception
573+
[`process.on('warning')`]: process.html#process_event_warning
565574
[stream]: stream.html
575+
[`--trace-warnings`]: cli.html#cli_trace_warnings

lib/events.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,14 @@ function _addListener(target, type, listener, prepend) {
256256
m = $getMaxListeners(target);
257257
if (m && m > 0 && existing.length > m) {
258258
existing.warned = true;
259-
process.emitWarning('Possible EventEmitter memory leak detected. ' +
259+
const w = new Error('Possible EventEmitter memory leak detected. ' +
260260
`${existing.length} ${type} listeners added. ` +
261261
'Use emitter.setMaxListeners() to increase limit');
262+
w.name = 'Warning';
263+
w.emitter = target;
264+
w.type = type;
265+
w.count = existing.length;
266+
process.emitWarning(w);
262267
}
263268
}
264269
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Flags: --no-warnings
2+
// The flag suppresses stderr output but the warning event will still emit
3+
'use strict';
4+
5+
const common = require('../common');
6+
const events = require('events');
7+
const assert = require('assert');
8+
9+
const e = new events.EventEmitter();
10+
e.setMaxListeners(1);
11+
12+
process.on('warning', common.mustCall((warning) => {
13+
assert.ok(warning instanceof Error);
14+
assert.strictEqual(warning.name, 'Warning');
15+
assert.strictEqual(warning.emitter, e);
16+
assert.strictEqual(warning.count, 2);
17+
assert.strictEqual(warning.type, 'event-type');
18+
}));
19+
20+
e.on('event-type', function() {});
21+
e.on('event-type', function() {});

0 commit comments

Comments
 (0)