Skip to content

Commit

Permalink
lib: add internal genericNodeError() function
Browse files Browse the repository at this point in the history
There are a few places in lib where `new Error()` is called and then
additional properties are attached in various ways. This creates a
utility function to generate the errors.

PR-URL: #41879
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
  • Loading branch information
Trott authored and danielleadams committed Apr 21, 2022
1 parent 73f3a2c commit 2a85e0a
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 50 deletions.
12 changes: 6 additions & 6 deletions lib/buffer.js
Expand Up @@ -25,7 +25,6 @@ const {
Array,
ArrayIsArray,
ArrayPrototypeForEach,
Error,
MathFloor,
MathMin,
MathTrunc,
Expand Down Expand Up @@ -99,7 +98,8 @@ const {
ERR_MISSING_ARGS,
ERR_UNKNOWN_ENCODING
},
hideStackFrames
genericNodeError,
hideStackFrames,
} = require('internal/errors');
const {
validateArray,
Expand Down Expand Up @@ -1207,10 +1207,10 @@ if (internalBinding('config').hasIntl) {
return result;

const code = icuErrName(result);
// eslint-disable-next-line no-restricted-syntax
const err = new Error(`Unable to transcode Buffer [${code}]`);
err.code = code;
err.errno = result;
const err = genericNodeError(
`Unable to transcode Buffer [${code}]`,
{ code: code, errno: result }
);
throw err;
};
}
Expand Down
19 changes: 8 additions & 11 deletions lib/child_process.js
Expand Up @@ -32,7 +32,6 @@ const {
ArrayPrototypeSort,
ArrayPrototypeSplice,
ArrayPrototypeUnshift,
Error,
NumberIsInteger,
ObjectAssign,
ObjectDefineProperty,
Expand Down Expand Up @@ -62,6 +61,7 @@ const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap');
const {
AbortError,
codes: errorCodes,
genericNodeError,
} = require('internal/errors');
const {
ERR_INVALID_ARG_VALUE,
Expand Down Expand Up @@ -395,11 +395,11 @@ function execFile(file, args = [], options, callback) {
cmd += ` ${ArrayPrototypeJoin(args, ' ')}`;

if (!ex) {
// eslint-disable-next-line no-restricted-syntax
ex = new Error('Command failed: ' + cmd + '\n' + stderr);
ex.killed = child.killed || killed;
ex.code = code < 0 ? getSystemErrorName(code) : code;
ex.signal = signal;
ex = genericNodeError(`Command failed: ${cmd}\n${stderr}`, {
code: code < 0 ? getSystemErrorName(code) : code,
killed: child.killed || killed,
signal: signal
});
}

ex.cmd = cmd;
Expand Down Expand Up @@ -819,16 +819,13 @@ function checkExecSyncError(ret, args, cmd) {
let err;
if (ret.error) {
err = ret.error;
ObjectAssign(err, ret);
} else if (ret.status !== 0) {
let msg = 'Command failed: ';
msg += cmd || ArrayPrototypeJoin(args, ' ');
if (ret.stderr && ret.stderr.length > 0)
msg += `\n${ret.stderr.toString()}`;
// eslint-disable-next-line no-restricted-syntax
err = new Error(msg);
}
if (err) {
ObjectAssign(err, ret);
err = genericNodeError(msg, ret);
}
return err;
}
Expand Down
14 changes: 5 additions & 9 deletions lib/events.js
Expand Up @@ -65,6 +65,7 @@ const {
ERR_OUT_OF_RANGE,
ERR_UNHANDLED_ERROR
},
genericNodeError,
} = require('internal/errors');

const {
Expand Down Expand Up @@ -597,15 +598,10 @@ function _addListener(target, type, listener, prepend) {
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
// No error code for this since it is a Warning
// eslint-disable-next-line no-restricted-syntax
const w = new Error('Possible EventEmitter memory leak detected. ' +
`${existing.length} ${String(type)} listeners ` +
`added to ${inspect(target, { depth: -1 })}. Use ` +
'emitter.setMaxListeners() to increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
const w = genericNodeError(
`Possible EventEmitter memory leak detected. ${existing.length} ${String(type)} listeners ` +
`added to ${inspect(target, { depth: -1 })}. Use emitter.setMaxListeners() to increase limit`,
{ name: 'MaxListenersExceededWarning', emitter: target, type: type, count: existing.length });
process.emitWarning(w);
}
}
Expand Down
45 changes: 31 additions & 14 deletions lib/internal/errors.js
Expand Up @@ -33,6 +33,7 @@ const {
MathMax,
Number,
NumberIsInteger,
ObjectAssign,
ObjectDefineProperty,
ObjectDefineProperties,
ObjectIsExtensible,
Expand Down Expand Up @@ -827,34 +828,50 @@ class AbortError extends Error {
this.name = 'AbortError';
}
}

/**
* This creates a generic Node.js error.
*
* @param {string} message The error message.
* @param {object} errorProperties Object with additional properties to be added to the error.
* @returns {Error}
*/
const genericNodeError = hideStackFrames(function genericNodeError(message, errorProperties) {
// eslint-disable-next-line no-restricted-syntax
const err = new Error(message);
ObjectAssign(err, errorProperties);
return err;
});

module.exports = {
AbortError,
aggregateTwoErrors,
captureLargerStackTrace,
codes,
connResetException,
dnsException,
// This is exported only to facilitate testing.
E,
errnoException,
exceptionWithHostPort,
fatalExceptionStackEnhancers,
genericNodeError,
getMessage,
hideStackFrames,
hideInternalStackFrames,
hideStackFrames,
isErrorStackTraceLimitWritable,
isStackOverflowError,
kEnhanceStackBeforeInspector,
kIsNodeError,
kNoOverride,
maybeOverridePrepareStackTrace,
overrideStackTrace,
prepareStackTrace,
setArrowMessage,
connResetException,
SystemError,
uvErrmapGet,
uvException,
uvExceptionWithHostPort,
SystemError,
AbortError,
// This is exported only to facilitate testing.
E,
kNoOverride,
prepareStackTrace,
maybeOverridePrepareStackTrace,
overrideStackTrace,
kEnhanceStackBeforeInspector,
fatalExceptionStackEnhancers,
kIsNodeError,
captureLargerStackTrace,
};

// To declare an error message, use the E(sym, val, def) function above. The sym
Expand Down
11 changes: 6 additions & 5 deletions lib/net.js
Expand Up @@ -25,7 +25,6 @@ const {
ArrayIsArray,
ArrayPrototypeIndexOf,
Boolean,
Error,
Number,
NumberIsNaN,
NumberParseInt,
Expand Down Expand Up @@ -97,7 +96,8 @@ const {
},
errnoException,
exceptionWithHostPort,
uvExceptionWithHostPort
genericNodeError,
uvExceptionWithHostPort,
} = require('internal/errors');
const { isUint8Array } = require('internal/util/types');
const {
Expand Down Expand Up @@ -484,9 +484,10 @@ function writeAfterFIN(chunk, encoding, cb) {
encoding = null;
}

// eslint-disable-next-line no-restricted-syntax
const er = new Error('This socket has been ended by the other party');
er.code = 'EPIPE';
const er = genericNodeError(
'This socket has been ended by the other party',
{ code: 'EPIPE' }
);
if (typeof cb === 'function') {
defaultTriggerAsyncIdScope(this[async_id_symbol], process.nextTick, cb, er);
}
Expand Down
7 changes: 3 additions & 4 deletions lib/zlib.js
Expand Up @@ -26,7 +26,6 @@ const {
ArrayPrototypeForEach,
ArrayPrototypeMap,
ArrayPrototypePush,
Error,
FunctionPrototypeBind,
MathMaxApply,
NumberIsFinite,
Expand All @@ -51,7 +50,8 @@ const {
ERR_OUT_OF_RANGE,
ERR_ZLIB_INITIALIZATION_FAILED,
},
hideStackFrames
genericNodeError,
hideStackFrames,
} = require('internal/errors');
const { Transform, finished } = require('stream');
const {
Expand Down Expand Up @@ -186,8 +186,7 @@ function zlibOnError(message, errno, code) {
// There is no way to cleanly recover.
// Continuing only obscures problems.

// eslint-disable-next-line no-restricted-syntax
const error = new Error(message);
const error = genericNodeError(message, { errno, code });
error.errno = errno;
error.code = code;
self.destroy(error);
Expand Down
2 changes: 1 addition & 1 deletion test/sequential/test-child-process-execsync.js
Expand Up @@ -60,7 +60,7 @@ try {
assert.ok(caught, 'execSync should throw');
const end = Date.now() - start;
assert(end < SLEEP);
assert(err.status > 128 || err.signal);
assert(err.status > 128 || err.signal, `status: ${err.status}, signal: ${err.signal}`);
}

assert.throws(function() {
Expand Down

0 comments on commit 2a85e0a

Please sign in to comment.