Skip to content

Commit

Permalink
events: give subclass name in unhandled 'error' message
Browse files Browse the repository at this point in the history
For unhandled `'error'` events, include the constructor name for
subclasses of EventEmitter, if possible. This makes tracing errors
easier when both creation of the `Error` object and emitting it
happen in code that does not refer back to the event emitter.

PR-URL: nodejs#28952
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
addaleax authored and Trott committed Aug 7, 2019
1 parent 320402c commit 4c9fb0b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
10 changes: 8 additions & 2 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,13 @@ function identicalSequenceRange(a, b) {
}

function enhanceStackTrace(err, own) {
const sep = '\nEmitted \'error\' event at:\n';
let ctorInfo = '';
try {
const { name } = this.constructor;
if (name !== 'EventEmitter')
ctorInfo = ` on ${name} instance`;
} catch {}
const sep = `\nEmitted 'error' event${ctorInfo} at:\n`;

const errStack = err.stack.split('\n').slice(1);
const ownStack = own.stack.split('\n').slice(1);
Expand Down Expand Up @@ -170,7 +176,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
// eslint-disable-next-line no-restricted-syntax
Error.captureStackTrace(capture, EventEmitter.prototype.emit);
Object.defineProperty(er, kEnhanceStackBeforeInspector, {
value: enhanceStackTrace.bind(null, er, capture),
value: enhanceStackTrace.bind(this, er, capture),
configurable: true
});
} catch {}
Expand Down
5 changes: 5 additions & 0 deletions test/message/events_unhandled_error_subclass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';
require('../common');
const EventEmitter = require('events');
class Foo extends EventEmitter {}
new Foo().emit('error', new Error());
17 changes: 17 additions & 0 deletions test/message/events_unhandled_error_subclass.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
events.js:*
throw er; // Unhandled 'error' event
^

Error
at Object.<anonymous> (*events_unhandled_error_subclass.js:*:*)
at Module._compile (internal/modules/cjs/loader.js:*:*)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*)
at Module.load (internal/modules/cjs/loader.js:*:*)
at Function.Module._load (internal/modules/cjs/loader.js:*:*)
at Function.Module.runMain (internal/modules/cjs/loader.js:*:*)
at internal/main/run_main_module.js:*:*
Emitted 'error' event on Foo instance at:
at Object.<anonymous> (*events_unhandled_error_subclass.js:*:*)
at Module._compile (internal/modules/cjs/loader.js:*:*)
[... lines matching original stack trace ...]
at internal/main/run_main_module.js:*:*

0 comments on commit 4c9fb0b

Please sign in to comment.