Skip to content

Commit 3fe1e80

Browse files
committed
lib: validate Error.captureStackTrace() calls
This adds a custom eslint rule to verify that `Error.captureStackTrace()` is only called if necessary. In most cases the helper function should be used instead. PR-URL: #26738 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent bfbce28 commit 3fe1e80

File tree

9 files changed

+15
-0
lines changed

9 files changed

+15
-0
lines changed

lib/.eslintrc.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ rules:
1515
# Config specific to lib
1616
- selector: "NewExpression[callee.name=/Error$/]:not([callee.name=/^(AssertionError|NghttpError)$/])"
1717
message: "Use an error exported by the internal/errors module."
18+
- selector: "CallExpression[callee.object.name='Error'][callee.property.name='captureStackTrace']"
19+
message: "Please use `require('internal/errors').hideStackFrames()` instead."
1820
# Custom rules in tools/eslint-rules
1921
node-core/require-globals: error
2022
node-core/no-let-in-for-declaration: error

lib/assert.js

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ function getErrMessage(message, fn) {
240240
// We only need the stack trace. To minimize the overhead use an object
241241
// instead of an error.
242242
const err = {};
243+
// eslint-disable-next-line no-restricted-syntax
243244
Error.captureStackTrace(err, fn);
244245
Error.stackTraceLimit = tmpLimit;
245246

lib/events.js

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
158158
try {
159159
const { kExpandStackSymbol } = require('internal/util');
160160
const capture = {};
161+
// eslint-disable-next-line no-restricted-syntax
161162
Error.captureStackTrace(capture, EventEmitter.prototype.emit);
162163
Object.defineProperty(er, kExpandStackSymbol, {
163164
value: enhanceStackTrace.bind(null, er, capture),

lib/fs.js

+2
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,15 @@ function showTruncateDeprecation() {
117117
function handleErrorFromBinding(ctx) {
118118
if (ctx.errno !== undefined) { // libuv error numbers
119119
const err = uvException(ctx);
120+
// eslint-disable-next-line no-restricted-syntax
120121
Error.captureStackTrace(err, handleErrorFromBinding);
121122
throw err;
122123
}
123124
if (ctx.error !== undefined) { // errors created in C++ land.
124125
// TODO(joyeecheung): currently, ctx.error are encoding errors
125126
// usually caused by memory problems. We need to figure out proper error
126127
// code(s) for this.
128+
// eslint-disable-next-line no-restricted-syntax
127129
Error.captureStackTrace(ctx.error, handleErrorFromBinding);
128130
throw ctx.error;
129131
}

lib/internal/assert/assertion_error.js

+1
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class AssertionError extends Error {
398398
this.actual = actual;
399399
this.expected = expected;
400400
this.operator = operator;
401+
// eslint-disable-next-line no-restricted-syntax
401402
Error.captureStackTrace(this, stackStartFn);
402403
// Create error message including the error code in the name.
403404
this.stack;

lib/internal/async_hooks.js

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ function fatalError(e) {
105105
process._rawDebug(e.stack);
106106
} else {
107107
const o = { message: e };
108+
// eslint-disable-next-line no-restricted-syntax
108109
Error.captureStackTrace(o, fatalError);
109110
process._rawDebug(o.stack);
110111
}

lib/internal/console/constructor.js

+1
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ const consoleMethods = {
331331
name: 'Trace',
332332
message: this[kFormatForStderr](args)
333333
};
334+
// eslint-disable-next-line no-restricted-syntax
334335
Error.captureStackTrace(err, this.trace);
335336
this.error(err.stack);
336337
},

lib/internal/errors.js

+5
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ function uvException(ctx) {
354354
err.dest = dest;
355355
}
356356

357+
// eslint-disable-next-line no-restricted-syntax
357358
Error.captureStackTrace(err, excludedStackFn || uvException);
358359
return err;
359360
}
@@ -396,6 +397,7 @@ function uvExceptionWithHostPort(err, syscall, address, port) {
396397
ex.port = port;
397398
}
398399

400+
// eslint-disable-next-line no-restricted-syntax
399401
Error.captureStackTrace(ex, excludedStackFn || uvExceptionWithHostPort);
400402
return ex;
401403
}
@@ -424,6 +426,7 @@ function errnoException(err, syscall, original) {
424426
ex.code = ex.errno = code;
425427
ex.syscall = syscall;
426428

429+
// eslint-disable-next-line no-restricted-syntax
427430
Error.captureStackTrace(ex, excludedStackFn || errnoException);
428431
return ex;
429432
}
@@ -472,6 +475,7 @@ function exceptionWithHostPort(err, syscall, address, port, additional) {
472475
ex.port = port;
473476
}
474477

478+
// eslint-disable-next-line no-restricted-syntax
475479
Error.captureStackTrace(ex, excludedStackFn || exceptionWithHostPort);
476480
return ex;
477481
}
@@ -512,6 +516,7 @@ function dnsException(code, syscall, hostname) {
512516
ex.hostname = hostname;
513517
}
514518

519+
// eslint-disable-next-line no-restricted-syntax
515520
Error.captureStackTrace(ex, excludedStackFn || dnsException);
516521
return ex;
517522
}

lib/internal/process/warning.js

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ function emitWarning(warning, type, code, ctor, now) {
112112
warning.name = String(type || 'Warning');
113113
if (code !== undefined) warning.code = code;
114114
if (detail !== undefined) warning.detail = detail;
115+
// eslint-disable-next-line no-restricted-syntax
115116
Error.captureStackTrace(warning, ctor || process.emitWarning);
116117
} else if (!(warning instanceof Error)) {
117118
throw new ERR_INVALID_ARG_TYPE('warning', ['Error', 'string'], warning);

0 commit comments

Comments
 (0)