diff --git a/benchmark/error/error.js b/benchmark/error/error.js deleted file mode 100644 index c856f3e07f6bea..00000000000000 --- a/benchmark/error/error.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -const common = require('../common.js'); - -const bench = common.createBenchmark(main, { - n: [1e7], -}); - -function main({ n }) { - bench.start(); - for (let i = 0; i < n; ++i) - new Error('test'); - bench.end(n); -} diff --git a/benchmark/misc/hidestackframes.js b/benchmark/error/hidestackframes.js similarity index 66% rename from benchmark/misc/hidestackframes.js rename to benchmark/error/hidestackframes.js index b28be725a30969..c57b84df16242b 100644 --- a/benchmark/misc/hidestackframes.js +++ b/benchmark/error/hidestackframes.js @@ -5,12 +5,23 @@ const common = require('../common.js'); const bench = common.createBenchmark(main, { type: ['hide-stackframes-throw', 'direct-call-throw', 'hide-stackframes-noerr', 'direct-call-noerr'], - n: [10e4], + n: [1e4], + nested: [1, 0], }, { flags: ['--expose-internals'], }); -function main({ n, type }) { +function nestIt(fn, i = 25) { + const nested = (...args) => { + return fn(...args); + }; + if (i === 0) { + return nested; + } + return nestIt(nested, i - 1); +} + +function main({ n, type, nested }) { const { hideStackFrames, codes: { @@ -24,9 +35,14 @@ function main({ n, type }) { } }; - let fn = testfn; - if (type.startsWith('hide-stackframe')) - fn = hideStackFrames(testfn); + let fn = type.startsWith('hide-stackframe') ? + hideStackFrames(testfn) : + testfn; + + if (nested) { + fn = nestIt(fn); + } + let value = 42; if (type.endsWith('-throw')) value = 'err'; diff --git a/benchmark/error/node-error.js b/benchmark/error/node-error.js index 3a0aef91f04a06..8f9cb5cad621fc 100644 --- a/benchmark/error/node-error.js +++ b/benchmark/error/node-error.js @@ -1,21 +1,34 @@ 'use strict'; const common = require('../common'); +const assert = require('assert'); const bench = common.createBenchmark(main, { - n: [1e7], + n: [1e5], + type: ['node', 'regular'], }, { flags: ['--expose-internals'], }); -function main({ n }) { +function main({ n, type }) { const { codes: { ERR_INVALID_STATE, }, } = require('internal/errors'); + + const Clazz = type === 'node' ? ERR_INVALID_STATE.TypeError : (() => { + class Foo extends TypeError {} + Foo.prototype.constructor = TypeError; + return Foo; + })(); + bench.start(); - for (let i = 0; i < n; ++i) - new ERR_INVALID_STATE.TypeError('test'); + let length = 0; + for (let i = 0; i < n; i++) { + const error = new Clazz('test' + i); + length += error.name.length; + } bench.end(n); + assert(length); } diff --git a/doc/api/errors.md b/doc/api/errors.md index 9139194719ade5..a1f0a0a0a2da35 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -2040,13 +2040,6 @@ which is not supported. The input may not be used in the [`REPL`][]. The conditions under which this error is used are described in the [`REPL`][] documentation. - - -### `ERR_INVALID_RETURN_PROPERTY` - -Thrown in case a function option does not provide a valid value for one of its -returned object properties on execution. - ### `ERR_INVALID_RETURN_PROPERTY_VALUE` @@ -3283,6 +3276,13 @@ removed: v15.0.0 An invalid or unknown file encoding was passed. + + +### `ERR_INVALID_RETURN_PROPERTY` + +Thrown in case a function option does not provide a valid value for one of its +returned object properties on execution. + ### `ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST` diff --git a/lib/assert.js b/lib/assert.js index 04c2dd3bfcfdfb..cdf6fa3b4e9260 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -57,7 +57,7 @@ const { ERR_INVALID_RETURN_VALUE, ERR_MISSING_ARGS, }, - isErrorStackTraceLimitWritable, + setStackTraceLimit, overrideStackTrace, } = require('internal/errors'); const AssertionError = require('internal/assert/assertion_error'); @@ -282,16 +282,15 @@ function parseCode(code, offset) { } function getErrMessage(message, fn) { - const tmpLimit = Error.stackTraceLimit; - const errorStackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); + const { stackTraceLimit } = Error; // Make sure the limit is set to 1. Otherwise it could fail (<= 0) or it // does to much work. - if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 1; + setStackTraceLimit(1); // We only need the stack trace. To minimize the overhead use an object // instead of an error. const err = {}; ErrorCaptureStackTrace(err, fn); - if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit; + setStackTraceLimit(stackTraceLimit); overrideStackTrace.set(err, (_, stack) => stack); const call = err.stack[0]; @@ -323,7 +322,7 @@ function getErrMessage(message, fn) { try { // Set the stack trace limit to zero. This makes sure unexpected token // errors are handled faster. - if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = 0; + setStackTraceLimit(0); if (filename) { if (decoder === undefined) { @@ -368,7 +367,7 @@ function getErrMessage(message, fn) { errorCache.set(identifier, undefined); } finally { // Reset limit. - if (errorStackTraceLimitIsWritable) Error.stackTraceLimit = tmpLimit; + setStackTraceLimit(stackTraceLimit); if (fd !== undefined) closeSync(fd); } diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index 851662fe4c5fa2..9eb62afc9af369 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -24,7 +24,7 @@ const colors = require('internal/util/colors'); const { validateObject, } = require('internal/validators'); -const { isErrorStackTraceLimitWritable } = require('internal/errors'); +const { setStackTraceLimit } = require('internal/errors'); const kReadableOperator = { @@ -337,8 +337,8 @@ class AssertionError extends Error { expected } = options; - const limit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + const { stackTraceLimit } = Error; + setStackTraceLimit(0); if (message != null) { super(String(message)); @@ -421,16 +421,18 @@ class AssertionError extends Error { } } - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; + setStackTraceLimit(stackTraceLimit); this.generatedMessage = !message; + ObjectDefineProperty(this, 'name', { __proto__: null, - value: 'AssertionError [ERR_ASSERTION]', + value: 'AssertionError', enumerable: false, writable: true, configurable: true }); + this.code = 'ERR_ASSERTION'; if (details) { this.actual = undefined; @@ -449,10 +451,6 @@ class AssertionError extends Error { this.operator = operator; } ErrorCaptureStackTrace(this, stackStartFn || stackStartFunction); - // Create error message including the error code in the name. - this.stack; // eslint-disable-line no-unused-expressions - // Reset the name. - this.name = 'AssertionError'; } toString() { diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index 1f0cc2d0a66ed9..ae9fcc942dc971 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -421,7 +421,10 @@ const consoleMethods = { trace: function trace(...args) { const err = { name: 'Trace', - message: this[kFormatForStderr](args) + message: this[kFormatForStderr](args), + toString() { + return `${this.name}: ${this.message}`; + } }; ErrorCaptureStackTrace(err, trace); this.error(err.stack); diff --git a/lib/internal/crypto/hkdf.js b/lib/internal/crypto/hkdf.js index 7f0fe5534ee843..cf3c39e8d9da5a 100644 --- a/lib/internal/crypto/hkdf.js +++ b/lib/internal/crypto/hkdf.js @@ -57,7 +57,7 @@ const validateParameters = hideStackFrames((hash, key, salt, info, length) => { validateInteger(length, 'length', 0, kMaxLength); if (info.byteLength > 1024) { - throw ERR_OUT_OF_RANGE( + throw new ERR_OUT_OF_RANGE( 'info', 'must not contain more than 1024 bytes', info.byteLength); diff --git a/lib/internal/debugger/inspect_client.js b/lib/internal/debugger/inspect_client.js index e467899fb3e746..24a9c683c68f2f 100644 --- a/lib/internal/debugger/inspect_client.js +++ b/lib/internal/debugger/inspect_client.js @@ -2,7 +2,6 @@ const { ArrayPrototypePush, - ErrorCaptureStackTrace, FunctionPrototypeBind, JSONParse, JSONStringify, @@ -12,10 +11,15 @@ const { const Buffer = require('buffer').Buffer; const crypto = require('crypto'); -const { ERR_DEBUGGER_ERROR } = require('internal/errors').codes; const { EventEmitter } = require('events'); const http = require('http'); const URL = require('url'); +const { + hideStackFrames, + codes: { + ERR_DEBUGGER_ERROR, + }, +} = require('internal/errors'); const debuglog = require('internal/util/debuglog').debuglog('inspect'); @@ -40,12 +44,11 @@ const kMaskingKeyWidthInBytes = 4; // https://tools.ietf.org/html/rfc6455#section-1.3 const WEBSOCKET_HANDSHAKE_GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; -function unpackError({ code, message }) { +const unpackError = hideStackFrames(({ code, message }) => { const err = new ERR_DEBUGGER_ERROR(`${message}`); err.code = code; - ErrorCaptureStackTrace(err, unpackError); return err; -} +}); function validateHandshake(requestKey, responseKey) { const expectedResponseKeyBase = requestKey + WEBSOCKET_HANDSHAKE_GUID; diff --git a/lib/internal/error_serdes.js b/lib/internal/error_serdes.js index 13f3f8b35fdab0..bc06357f0d09c4 100644 --- a/lib/internal/error_serdes.js +++ b/lib/internal/error_serdes.js @@ -146,7 +146,7 @@ function deserializeError(error) { return buf.toString('utf8'); } } - require('assert').fail('This should not happen'); + require('internal/assert').fail('This should not happen'); } module.exports = { serializeError, deserializeError }; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 742d723155e7fe..901e88993f1eb5 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -14,38 +14,31 @@ const { AggregateError, ArrayFrom, ArrayIsArray, - ArrayPrototypeFilter, ArrayPrototypeIncludes, ArrayPrototypeIndexOf, ArrayPrototypeJoin, ArrayPrototypeMap, ArrayPrototypePush, + ArrayPrototypeShift, ArrayPrototypeSlice, ArrayPrototypeSplice, - ArrayPrototypeUnshift, Error, - ErrorCaptureStackTrace, ErrorPrototypeToString, + FunctionPrototypeCall, JSONStringify, MapPrototypeGet, - MathAbs, MathMax, Number, - NumberIsInteger, ObjectAssign, ObjectDefineProperty, ObjectDefineProperties, - ObjectIsExtensible, - ObjectGetOwnPropertyDescriptor, ObjectKeys, - ObjectPrototypeHasOwnProperty, RangeError, ReflectApply, RegExpPrototypeExec, SafeArrayIterator, SafeMap, SafeWeakMap, - String, StringPrototypeEndsWith, StringPrototypeIncludes, StringPrototypeSlice, @@ -59,11 +52,10 @@ const { URIError, } = primordials; -const kIsNodeError = Symbol('kIsNodeError'); - const isWindows = process.platform === 'win32'; const messages = new SafeMap(); +const messageArguments = new SafeMap(); const codes = {}; const classRegExp = /^([A-Z][a-z0-9]*)+$/; @@ -83,55 +75,42 @@ const kTypes = [ const MainContextError = Error; const overrideStackTrace = new SafeWeakMap(); -const kNoOverride = Symbol('kNoOverride'); -let userStackTraceLimit; const nodeInternalPrefix = '__node_internal_'; -const prepareStackTrace = (globalThis, error, trace) => { - // API for node internals to override error stack formatting - // without interfering with userland code. - if (overrideStackTrace.has(error)) { - const f = overrideStackTrace.get(error); - overrideStackTrace.delete(error); - return f(error, trace); - } +const defaultFormatStackTrace = (errorString, trace) => { + return `${errorString}\n at ${ArrayPrototypeJoin(trace, '\n at ')}`; +}; +let formatStackTrace = defaultFormatStackTrace; + +function setFormatStackTrace(fn = defaultFormatStackTrace) { + formatStackTrace = fn; +} + +const prepareStackTrace = (globalThis, error, trace) => { + // Remove stack frames that should be hidden. const firstFrame = trace[0]?.getFunctionName(); if (firstFrame && StringPrototypeStartsWith(firstFrame, nodeInternalPrefix)) { - for (let l = trace.length - 1; l >= 0; l--) { - const fn = trace[l]?.getFunctionName(); + let i = trace.length - 1; + for (; i > 0; i--) { + const fn = trace[i]?.getFunctionName(); if (fn && StringPrototypeStartsWith(fn, nodeInternalPrefix)) { - ArrayPrototypeSplice(trace, 0, l + 1); + trace = ArrayPrototypeSlice(trace, i + 1); break; } } - // `userStackTraceLimit` is the user value for `Error.stackTraceLimit`, - // it is updated at every new exception in `captureLargerStackTrace`. - if (trace.length > userStackTraceLimit) - ArrayPrototypeSplice(trace, userStackTraceLimit); + if (i === 0) { + ArrayPrototypeShift(trace); + } } - const globalOverride = - maybeOverridePrepareStackTrace(globalThis, error, trace); - if (globalOverride !== kNoOverride) return globalOverride; - - // Normal error formatting: - // - // Error: Message - // at function (file) - // at file - let errorString; - if (kIsNodeError in error) { - errorString = `${error.name} [${error.code}]: ${error.message}`; - } else { - errorString = ErrorPrototypeToString(error); - } - if (trace.length === 0) { - return errorString; + // API for node internals to override error stack formatting + // without interfering with userland code. + const fn = overrideStackTrace.get(error); + if (fn !== undefined) { + overrideStackTrace.delete(error); + return fn(error, trace); } - return `${errorString}\n at ${ArrayPrototypeJoin(trace, '\n at ')}`; -}; -const maybeOverridePrepareStackTrace = (globalThis, error, trace) => { // Polyfill of V8's Error.prepareStackTrace API. // https://crbug.com/v8/7848 // `globalThis` is the global that contains the constructor which @@ -146,7 +125,26 @@ const maybeOverridePrepareStackTrace = (globalThis, error, trace) => { return MainContextError.prepareStackTrace(error, trace); } - return kNoOverride; + // Normal error formatting: + // + // Error: Message + // at function (file) + // at file + let errorString; + // Do not use primordials here: we intercept user code here. + const { toString } = error; + if (typeof toString === 'function') { + errorString = FunctionPrototypeCall(toString, error); + if (typeof errorString !== 'string' || StringPrototypeStartsWith(errorString, '[object ')) { + errorString = ErrorPrototypeToString(error); + } + } else { + errorString = ErrorPrototypeToString(error); + } + if (trace.length === 0) { + return errorString; + } + return formatStackTrace(errorString, trace); }; const aggregateTwoErrors = hideStackFrames((innerError, outerError) => { @@ -167,13 +165,6 @@ const aggregateTwoErrors = hideStackFrames((innerError, outerError) => { return innerError || outerError; }); -const aggregateErrors = hideStackFrames((errors, message, code) => { - // eslint-disable-next-line no-restricted-syntax - const err = new AggregateError(new SafeArrayIterator(errors), message); - err.code = errors[0]?.code; - return err; -}); - // Lazily loaded let util; let assert; @@ -196,21 +187,24 @@ function lazyBuffer() { return buffer; } -function isErrorStackTraceLimitWritable() { - // Do no touch Error.stackTraceLimit as V8 would attempt to install - // it again during deserialization. - if (require('internal/v8/startup_snapshot').namespace.isBuildingSnapshot()) { - return false; - } - - const desc = ObjectGetOwnPropertyDescriptor(Error, 'stackTraceLimit'); - if (desc === undefined) { - return ObjectIsExtensible(Error); +let stackTraceLimitWritable = 0; +function setStackTraceLimit(limit) { + if (stackTraceLimitWritable === 1) { + try { + Error.stackTraceLimit = limit; + } catch { + stackTraceLimitWritable = -1; + } + } else if (stackTraceLimitWritable === 0) { + // Do no touch Error.stackTraceLimit as V8 would attempt to install + // it again during deserialization. + if (require('internal/v8/startup_snapshot').namespace.isBuildingSnapshot()) { + stackTraceLimitWritable = -1; + return; + } + stackTraceLimitWritable = 1; + setStackTraceLimit(limit); } - - return ObjectPrototypeHasOwnProperty(desc, 'writable') ? - desc.writable : - desc.set !== undefined; } function inspectWithNoCustomRetry(obj, options) { @@ -233,12 +227,9 @@ function inspectWithNoCustomRetry(obj, options) { // and may have .path and .dest. class SystemError extends Error { constructor(key, context) { - const limit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; - super(); - // Reset the limit and setting the name property. - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; - const prefix = getMessage(key, [], this); + const msg = messages.get(key); + + const prefix = getMessage(key, msg, []); let message = `${prefix}: ${context.syscall} returned ` + `${context.code} (${context.message})`; @@ -247,18 +238,11 @@ class SystemError extends Error { if (context.dest !== undefined) message += ` => ${context.dest}`; - captureLargerStackTrace(this); + super(message); this.code = key; ObjectDefineProperties(this, { - [kIsNodeError]: { - __proto__: null, - value: true, - enumerable: false, - writable: false, - configurable: true, - }, name: { __proto__: null, value: 'SystemError', @@ -266,13 +250,6 @@ class SystemError extends Error { writable: true, configurable: true, }, - message: { - __proto__: null, - value: message, - enumerable: false, - writable: true, - configurable: true, - }, info: { __proto__: null, value: context, @@ -356,50 +333,53 @@ class SystemError extends Error { } function makeSystemErrorWithCode(key) { - return class NodeError extends SystemError { + const clazz = class NodeError extends SystemError { constructor(ctx) { super(key, ctx); } }; + // The constructor must be the Base class to align with the WPT tests. + SystemError.prototype.constructor = Error; + return clazz; } -function makeNodeErrorWithCode(Base, key) { - return function NodeError(...args) { - const limit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; - const error = new Base(); - // Reset the limit and setting the name property. - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; - const message = getMessage(key, args, error); - ObjectDefineProperties(error, { - [kIsNodeError]: { - __proto__: null, - value: true, - enumerable: false, - writable: false, - configurable: true, - }, - message: { - __proto__: null, - value: message, - enumerable: false, - writable: true, - configurable: true, - }, - toString: { - __proto__: null, - value() { - return `${this.name} [${key}]: ${this.message}`; - }, - enumerable: false, - writable: true, - configurable: true, - }, - }); - captureLargerStackTrace(error); - error.code = key; - return error; - }; +function makeNodeErrorWithCode(Base, key, val) { + let clazz; + if (typeof val === 'string') { + clazz = class NodeError extends Base { + constructor(...args) { + const message = getMessage(key, val, args); + super(message); + this.code = key; + } + + toString() { + return `${this.name} [${key}]: ${this.message}`; + } + }; + } else { + clazz = class NodeError extends Base { + constructor(...args) { + super(); + const message = getFnMessage(key, val, args, this); + ObjectDefineProperty(this, 'message', { + __proto__: null, + value: message, + enumerable: false, + writable: true, + configurable: true, + }); + this.code = key; + } + + toString() { + return `${this.name} [${key}]: ${this.message}`; + } + }; + } + // The constructor must be the Base class to align with the WPT tests. + clazz.prototype.constructor = Base; + return clazz; } /** @@ -421,48 +401,57 @@ function hideStackFrames(fn) { function E(sym, val, def, ...otherClasses) { // Special case for SystemError that formats the error message differently // The SystemErrors only have SystemError as their base classes. + if (typeof val === 'string') { + const regex = /%[dfijoOs]/g; + let expectedLength = 0; + while (RegExpPrototypeExec(regex, val) !== null) expectedLength++; + messageArguments.set(sym, expectedLength); + } else { + messageArguments.set(sym, val.length); + } messages.set(sym, val); if (def === SystemError) { def = makeSystemErrorWithCode(sym); } else { - def = makeNodeErrorWithCode(def, sym); + def = makeNodeErrorWithCode(def, sym, val); } if (otherClasses.length !== 0) { otherClasses.forEach((clazz) => { - def[clazz.name] = makeNodeErrorWithCode(clazz, sym); + def[clazz.name] = makeNodeErrorWithCode(clazz, sym, val); }); } codes[sym] = def; } -function getMessage(key, args, self) { - const msg = messages.get(key); +function getFnMessage(key, fn, args, self) { + assert ??= require('internal/assert'); + + const expectedLength = messageArguments.get(key); + + assert( + expectedLength <= args.length, + `Code: ${key}; The provided arguments length (${args.length}) does not ` + + `match the required ones (${expectedLength}).`, + ); + return ReflectApply(fn, self, args); +} +function getMessage(key, msg, args) { assert ??= require('internal/assert'); - if (typeof msg === 'function') { - assert( - msg.length <= args.length, // Default options do not count. - `Code: ${key}; The provided arguments length (${args.length}) does not ` + - `match the required ones (${msg.length}).`, - ); - return ReflectApply(msg, self, args); - } + const expectedLength = messageArguments.get(key); - const regex = /%[dfijoOs]/g; - let expectedLength = 0; - while (RegExpPrototypeExec(regex, msg) !== null) expectedLength++; assert( expectedLength === args.length, `Code: ${key}; The provided arguments length (${args.length}) does not ` + `match the required ones (${expectedLength}).`, ); + if (args.length === 0) return msg; - ArrayPrototypeUnshift(args, msg); - return ReflectApply(lazyInternalUtilInspect().format, null, args); + return lazyInternalUtilInspect().format(msg, ...args); } let uvBinding; @@ -480,20 +469,6 @@ function uvErrmapGet(name) { return MapPrototypeGet(uvBinding.errmap, name); } -const captureLargerStackTrace = hideStackFrames( - function captureLargerStackTrace(err) { - const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); - if (stackTraceLimitIsWritable) { - userStackTraceLimit = Error.stackTraceLimit; - Error.stackTraceLimit = Infinity; - } - ErrorCaptureStackTrace(err); - // Reset the limit - if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit; - - return err; - }); - /** * This creates an error compatible with errors produced in the C++ * function UVException using a context object with data assembled in C++. @@ -518,16 +493,10 @@ const uvException = hideStackFrames(function uvException(ctx) { message += ` -> '${dest}'`; } - // Reducing the limit improves the performance significantly. We do not lose - // the stack frames due to the `captureStackTrace()` function that is called - // later. - const tmpLimit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; // Pass the message to the constructor instead of setting it on the object // to make sure it is the same as the one created in C++ // eslint-disable-next-line no-restricted-syntax const err = new Error(message); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; for (const prop of ObjectKeys(ctx)) { if (prop === 'message' || prop === 'path' || prop === 'dest') { @@ -544,7 +513,7 @@ const uvException = hideStackFrames(function uvException(ctx) { err.dest = dest; } - return captureLargerStackTrace(err); + return err; }); /** @@ -570,14 +539,8 @@ const uvExceptionWithHostPort = hideStackFrames( details = ` ${address}`; } - // Reducing the limit improves the performance significantly. We do not - // lose the stack frames due to the `captureStackTrace()` function that - // is called later. - const tmpLimit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax const ex = new Error(`${message}${details}`); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; ex.code = code; ex.errno = err; ex.syscall = syscall; @@ -586,7 +549,7 @@ const uvExceptionWithHostPort = hideStackFrames( ex.port = port; } - return captureLargerStackTrace(ex); + return ex; }); /** @@ -608,16 +571,13 @@ const errnoException = hideStackFrames( const message = original ? `${syscall} ${code} ${original}` : `${syscall} ${code}`; - const tmpLimit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax const ex = new Error(message); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; ex.errno = err; ex.code = code; ex.syscall = syscall; - return captureLargerStackTrace(ex); + return ex; }); /** @@ -649,14 +609,8 @@ const exceptionWithHostPort = hideStackFrames( details += ` - Local (${additional})`; } - // Reducing the limit improves the performance significantly. We do not - // lose the stack frames due to the `captureStackTrace()` function that - // is called later. - const tmpLimit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; // eslint-disable-next-line no-restricted-syntax const ex = new Error(`${syscall} ${code}${details}`); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; ex.errno = err; ex.code = code; ex.syscall = syscall; @@ -665,7 +619,7 @@ const exceptionWithHostPort = hideStackFrames( ex.port = port; } - return captureLargerStackTrace(ex); + return ex; }); /** @@ -694,14 +648,9 @@ const dnsException = hideStackFrames(function(code, syscall, hostname) { } } const message = `${syscall} ${code}${hostname ? ` ${hostname}` : ''}`; - // Reducing the limit improves the performance significantly. We do not lose - // the stack frames due to the `captureStackTrace()` function that is called - // later. - const tmpLimit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + // eslint-disable-next-line no-restricted-syntax const ex = new Error(message); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpLimit; ex.errno = errno; ex.code = code; ex.syscall = syscall; @@ -709,7 +658,7 @@ const dnsException = hideStackFrames(function(code, syscall, hostname) { ex.hostname = hostname; } - return captureLargerStackTrace(ex); + return ex; }); function connResetException(msg) { @@ -744,17 +693,6 @@ function isStackOverflowError(err) { err.message === maxStack_ErrorMessage; } -// Only use this for integers! Decimal numbers do not work with this function. -function addNumericalSeparator(val) { - let res = ''; - let i = val.length; - const start = val[0] === '-' ? 1 : 0; - for (; i >= start + 4; i -= 3) { - res = `_${StringPrototypeSlice(val, i - 3, i)}${res}`; - } - return `${StringPrototypeSlice(val, 0, i)}${res}`; -} - // Used to enhance the stack that will be picked up by the inspector const kEnhanceStackBeforeInspector = Symbol('kEnhanceStackBeforeInspector'); @@ -828,16 +766,20 @@ function setArrowMessage(err, arrowMessage) { // Hide stack lines before the first user code line. function hideInternalStackFrames(error) { overrideStackTrace.set(error, (error, stackFrames) => { - let frames = stackFrames; + let result = ''; if (typeof stackFrames === 'object') { - frames = ArrayPrototypeFilter( - stackFrames, - (frm) => !StringPrototypeStartsWith(frm.getFileName() || '', - 'node:internal'), - ); + for (const frame of stackFrames) { + const filename = frame.getFileName(); + if (!filename || !StringPrototypeStartsWith(filename, 'node:internal')) { + result += `\n at ${frame}`; + } + } + } else { + for (const frame of stackFrames) { + result += `\n at ${frame}`; + } } - ArrayPrototypeUnshift(frames, error); - return ArrayPrototypeJoin(frames, '\n at '); + return error + result; }); } @@ -910,8 +852,6 @@ function formatList(array, type = 'and') { module.exports = { AbortError, aggregateTwoErrors, - aggregateErrors, - captureLargerStackTrace, codes, connResetException, dnsException, @@ -923,16 +863,15 @@ module.exports = { fatalExceptionStackEnhancers, formatList, genericNodeError, + messages, getMessage, hideInternalStackFrames, hideStackFrames, inspectWithNoCustomRetry, - isErrorStackTraceLimitWritable, + setStackTraceLimit, isStackOverflowError, kEnhanceStackBeforeInspector, - kIsNodeError, - kNoOverride, - maybeOverridePrepareStackTrace, + setFormatStackTrace, overrideStackTrace, prepareStackTrace, setArrowMessage, @@ -1342,10 +1281,6 @@ E('ERR_INVALID_PROTOCOL', E('ERR_INVALID_REPL_EVAL_CONFIG', 'Cannot specify both "breakEvalOnSigint" and "eval" for REPL', TypeError); E('ERR_INVALID_REPL_INPUT', '%s', TypeError); -E('ERR_INVALID_RETURN_PROPERTY', (input, name, prop, value) => { - return `Expected a valid ${input} to be returned for the "${prop}" from the` + - ` "${name}" function but got ${value}.`; -}, TypeError); E('ERR_INVALID_RETURN_PROPERTY_VALUE', (input, name, prop, value) => { let type; if (value?.constructor?.name) { @@ -1448,9 +1383,7 @@ E('ERR_MISSING_ARGS', return `${msg} must be specified`; }, TypeError); E('ERR_MISSING_OPTION', '%s is required', TypeError); -E('ERR_MODULE_NOT_FOUND', (path, base, type = 'package') => { - return `Cannot find ${type} '${path}' imported from ${base}`; -}, Error); +E('ERR_MODULE_NOT_FOUND', "Cannot find %s '%s' imported from %s", Error); E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times', Error); E('ERR_NAPI_CONS_FUNCTION', 'Constructor must be a function', TypeError); E('ERR_NAPI_INVALID_DATAVIEW_ARGS', @@ -1477,18 +1410,7 @@ E('ERR_OUT_OF_RANGE', assert(range, 'Missing "range" argument'); let msg = replaceDefaultBoolean ? str : `The value of "${str}" is out of range.`; - let received; - if (NumberIsInteger(input) && MathAbs(input) > 2 ** 32) { - received = addNumericalSeparator(String(input)); - } else if (typeof input === 'bigint') { - received = String(input); - if (input > 2n ** 32n || input < -(2n ** 32n)) { - received = addNumericalSeparator(received); - } - received += 'n'; - } else { - received = lazyInternalUtilInspect().inspect(input); - } + const received = lazyInternalUtilInspect().inspect(input, { numericSeparator: true }); msg += ` It must be ${range}. Received ${received}`; return msg; }, RangeError); @@ -1602,7 +1524,7 @@ E('ERR_TAP_VALIDATION_ERROR', function(errorMsg) { hideInternalStackFrames(this); return errorMsg; }, Error); -E('ERR_TEST_FAILURE', function(error, failureType) { +E('ERR_TEST_FAILURE', function(error, failureType, extraProperties = undefined) { hideInternalStackFrames(this); assert(typeof failureType === 'string' || typeof failureType === 'symbol', "The 'failureType' argument must be of type string or symbol."); @@ -1615,6 +1537,9 @@ E('ERR_TEST_FAILURE', function(error, failureType) { this.failureType = failureType; this.cause = error; + if (extraProperties !== undefined) { + ObjectAssign(this, extraProperties); + } return msg; }, Error); E('ERR_TLS_CERT_ALTNAME_FORMAT', 'Invalid subject alternative name string', diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index f75d0fba917241..5f65007a3b540e 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -141,8 +141,8 @@ function importFd(stream, options) { return options.fd.fd; } - throw ERR_INVALID_ARG_TYPE('options.fd', - ['number', 'FileHandle'], options.fd); + throw new ERR_INVALID_ARG_TYPE('options.fd', + ['number', 'FileHandle'], options.fd); } function ReadStream(path, options) { diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 4fb27d9a52aa3b..dcd7619d37d627 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -42,7 +42,7 @@ const { assertCrypto(); -const assert = require('assert'); +const assert = require('internal/assert'); const EventEmitter = require('events'); const fs = require('fs'); const http = require('http'); @@ -418,7 +418,9 @@ function onSessionHeaders(handle, id, cat, flags, headers, sensitiveHeaders) { function tryClose(fd) { // Try to close the file descriptor. If closing fails, assert because // an error really should not happen at this point. - fs.close(fd, assert.ifError); + fs.close(fd, (error) => { + if (error != null) require('assert').ifError(error); + }); } // Called when the Http2Stream has finished sending data and is ready for diff --git a/lib/internal/http2/util.js b/lib/internal/http2/util.js index 850c8f74019048..6c16a6e1125d40 100644 --- a/lib/internal/http2/util.js +++ b/lib/internal/http2/util.js @@ -8,7 +8,6 @@ const { Error, MathMax, Number, - ObjectDefineProperty, ObjectKeys, SafeSet, String, @@ -28,10 +27,9 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_HTTP_TOKEN }, - captureLargerStackTrace, + messages, getMessage, hideStackFrames, - kIsNodeError, } = require('internal/errors'); const kSensitiveHeaders = Symbol('nodejs.http2.sensitiveHeaders'); @@ -547,19 +545,12 @@ function mapToHeaders(map, class NghttpError extends Error { constructor(integerCode, customErrorCode) { + const msg = messages.get(customErrorCode); super(customErrorCode ? - getMessage(customErrorCode, [], null) : + getMessage(customErrorCode, msg, []) : binding.nghttp2ErrorString(integerCode)); this.code = customErrorCode || 'ERR_HTTP2_ERROR'; this.errno = integerCode; - captureLargerStackTrace(this); - ObjectDefineProperty(this, kIsNodeError, { - __proto__: null, - value: true, - enumerable: false, - writable: false, - configurable: true, - }); } toString() { diff --git a/lib/internal/main/print_help.js b/lib/internal/main/print_help.js index 4f07aedf1b6e82..631326edb91f8e 100644 --- a/lib/internal/main/print_help.js +++ b/lib/internal/main/print_help.js @@ -110,7 +110,7 @@ function getArgDescription(type) { case 'kStringList': return '...'; default: - require('assert').fail(`unknown option type ${type}`); + require('internal/assert').fail(`unknown option type ${type}`); } } diff --git a/lib/internal/modules/esm/fetch_module.js b/lib/internal/modules/esm/fetch_module.js index d79e5a5eb99e84..89d62016454dbd 100644 --- a/lib/internal/modules/esm/fetch_module.js +++ b/lib/internal/modules/esm/fetch_module.js @@ -144,7 +144,7 @@ function fetchWithRedirects(parsed) { return entry; } if (res.statusCode === 404) { - const err = new ERR_MODULE_NOT_FOUND(parsed.href, null); + const err = new ERR_MODULE_NOT_FOUND('package', parsed.href, null); err.message = `Cannot find module '${parsed.href}', HTTP 404`; throw err; } diff --git a/lib/internal/modules/esm/hooks.js b/lib/internal/modules/esm/hooks.js index 83e5038903df83..3ee2ac7798e4eb 100644 --- a/lib/internal/modules/esm/hooks.js +++ b/lib/internal/modules/esm/hooks.js @@ -500,7 +500,7 @@ class Hooks { !isAnyArrayBuffer(source) && !isArrayBufferView(source) ) { - throw ERR_INVALID_RETURN_PROPERTY_VALUE( + throw new ERR_INVALID_RETURN_PROPERTY_VALUE( 'a string, an ArrayBuffer, or a TypedArray', hookErrIdentifier, 'source', diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 194d2ba37bf3b2..bd79009cd0a449 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -200,7 +200,10 @@ function legacyMainResolve(packageJSONUrl, packageConfig, base) { } // Not found. throw new ERR_MODULE_NOT_FOUND( - fileURLToPath(new URL('.', packageJSONUrl)), fileURLToPath(base)); + 'package', + fileURLToPath(new URL('.', packageJSONUrl)), + fileURLToPath(base), + ); } const encodedSepRegEx = /%2F|%5C/i; @@ -229,7 +232,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) { process.send({ 'watch:require': [path || resolved.pathname] }); } throw new ERR_MODULE_NOT_FOUND( - path || resolved.pathname, base && fileURLToPath(base), 'module'); + 'module', path || resolved.pathname, base && fileURLToPath(base)); } if (!preserveSymlinks) { @@ -791,7 +794,7 @@ function packageResolve(specifier, base, conditions) { // eslint can't handle the above code. // eslint-disable-next-line no-unreachable - throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)); + throw new ERR_MODULE_NOT_FOUND('package', packageName, fileURLToPath(base)); } /** diff --git a/lib/internal/process/promises.js b/lib/internal/process/promises.js index d80ce1ef764a00..0c96e52e66d289 100644 --- a/lib/internal/process/promises.js +++ b/lib/internal/process/promises.js @@ -36,7 +36,7 @@ const { trigger_async_id_symbol: kTriggerAsyncIdSymbol, }, } = require('internal/async_hooks'); -const { isErrorStackTraceLimitWritable } = require('internal/errors'); +const { setStackTraceLimit } = require('internal/errors'); // *Must* match Environment::TickInfo::Fields in src/env.h. const kHasRejectionToWarn = 1; @@ -315,11 +315,11 @@ function processPromiseRejections() { function getErrorWithoutStack(name, message) { // Reset the stack to prevent any overhead. - const tmp = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + const { stackTraceLimit } = Error; + setStackTraceLimit(0); // eslint-disable-next-line no-restricted-syntax const err = new Error(message); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmp; + setStackTraceLimit(stackTraceLimit); ObjectDefineProperty(err, 'name', { __proto__: null, value: name, diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index 3ce00004dab476..fb1b50b7e664bd 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -13,7 +13,7 @@ const { codes: { ERR_INVALID_ARG_TYPE, }, - isErrorStackTraceLimitWritable, + setStackTraceLimit, } = require('internal/errors'); const { validateString } = require('internal/validators'); @@ -174,11 +174,11 @@ function createWarningObject(warning, type, code, ctor, detail) { assert(typeof warning === 'string'); // Improve error creation performance by skipping the error frames. // They are added in the `captureStackTrace()` function below. - const tmpStackLimit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + const { stackTraceLimit } = Error; + setStackTraceLimit(0); // eslint-disable-next-line no-restricted-syntax warning = new Error(warning); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmpStackLimit; + setStackTraceLimit(stackTraceLimit); warning.name = String(type || 'Warning'); if (code !== undefined) warning.code = code; if (detail !== undefined) warning.detail = detail; diff --git a/lib/internal/source_map/prepare_stack_trace.js b/lib/internal/source_map/prepare_stack_trace.js index 860564f4a34ab5..2445779dfffcb4 100644 --- a/lib/internal/source_map/prepare_stack_trace.js +++ b/lib/internal/source_map/prepare_stack_trace.js @@ -1,10 +1,8 @@ 'use strict'; const { + ArrayPrototypeForEach, ArrayPrototypeIndexOf, - ArrayPrototypeJoin, - ArrayPrototypeMap, - ErrorPrototypeToString, RegExpPrototypeSymbolSplit, StringPrototypeRepeat, StringPrototypeSlice, @@ -18,53 +16,23 @@ let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => { const { getStringWidth } = require('internal/util/inspect'); const { readFileSync } = require('fs'); const { findSourceMap } = require('internal/source_map/source_map_cache'); -const { - kNoOverride, - overrideStackTrace, - maybeOverridePrepareStackTrace, - kIsNodeError, -} = require('internal/errors'); const { fileURLToPath } = require('internal/url'); const { setGetSourceMapErrorSource } = internalBinding('errors'); // Create a prettified stacktrace, inserting context from source maps // if possible. -const prepareStackTrace = (globalThis, error, trace) => { - // API for node internals to override error stack formatting - // without interfering with userland code. - // TODO(bcoe): add support for source-maps to repl. - if (overrideStackTrace.has(error)) { - const f = overrideStackTrace.get(error); - overrideStackTrace.delete(error); - return f(error, trace); - } - - const globalOverride = - maybeOverridePrepareStackTrace(globalThis, error, trace); - if (globalOverride !== kNoOverride) return globalOverride; - - let errorString; - if (kIsNodeError in error) { - errorString = `${error.name} [${error.code}]: ${error.message}`; - } else { - errorString = ErrorPrototypeToString(error); - } - - if (trace.length === 0) { - return errorString; - } - +function formatStackTrace(errorString, trace) { let lastSourceMap; let lastFileName; - const preparedTrace = ArrayPrototypeJoin(ArrayPrototypeMap(trace, (t, i) => { + let preparedTrace = ''; + + ArrayPrototypeForEach(trace, (t, i) => { const str = i !== 0 ? '\n at ' : ''; try { // A stack trace will often have several call sites in a row within the // same file, cache the source map and file content accordingly: - let fileName = t.getFileName(); - if (fileName === undefined) { - fileName = t.getEvalOrigin(); - } + const fileName = t.getFileName() ?? t.getEvalOrigin(); + const sm = fileName === lastFileName ? lastSourceMap : findSourceMap(fileName); @@ -96,18 +64,19 @@ const prepareStackTrace = (globalThis, error, trace) => { StringPrototypeStartsWith(originalSource, 'file://') ? fileURLToPath(originalSource) : originalSource; // Replace the transpiled call site with the original: - return `${str}${prefix}${hasName ? ' (' : ''}` + + preparedTrace += `${str}${prefix}${hasName ? ' (' : ''}` + `${originalSourceNoScheme}:${originalLine + 1}:` + `${originalColumn + 1}${hasName ? ')' : ''}`; + return; } } } catch (err) { debug(err); } - return `${str}${t}`; - }), ''); + preparedTrace += `${str}${t}`; + }); return `${errorString}\n at ${preparedTrace}`; -}; +} // Transpilers may have removed the original symbol name used in the stack // trace, if possible restore it from the names field of the source map: @@ -210,5 +179,5 @@ function getSourceMapErrorSource(fileName, lineNumber, columnNumber) { setGetSourceMapErrorSource(getSourceMapErrorSource); module.exports = { - prepareStackTrace, + formatStackTrace, }; diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index ee1f9c404e8b6f..8a512d7084fa12 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -56,18 +56,23 @@ function setSourceMapsEnabled(val) { setSourceMapsEnabled, setPrepareStackTraceCallback, } = internalBinding('errors'); + setSourceMapsEnabled(val); + + const { + setFormatStackTrace, + prepareStackTrace, + } = require('internal/errors'); + + setPrepareStackTraceCallback(prepareStackTrace); if (val) { const { - prepareStackTrace, + formatStackTrace, } = require('internal/source_map/prepare_stack_trace'); - setPrepareStackTraceCallback(prepareStackTrace); + setFormatStackTrace(formatStackTrace); } else if (sourceMapsEnabled !== undefined) { // Reset prepare stack trace callback only when disabling source maps. - const { - prepareStackTrace, - } = require('internal/errors'); - setPrepareStackTraceCallback(prepareStackTrace); + setFormatStackTrace(); } sourceMapsEnabled = val; diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index 7a2aad41ee2baa..54eb8a9073ea7c 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -370,10 +370,10 @@ Readable.prototype.setEncoding = function(enc) { }; // Don't raise the hwm > 1GB. -const MAX_HWM = 0x40000000; +const MAX_HWM = 1_073_741_824; function computeNewHighWaterMark(n) { if (n > MAX_HWM) { - throw new ERR_OUT_OF_RANGE('size', '<= 1GiB', n); + throw new ERR_OUT_OF_RANGE('size', `<= ${MAX_HWM}`, n); } else { // Get the next highest power of 2 to prevent increasing hwm excessively in // tiny amounts. diff --git a/lib/internal/test_runner/reporter/spec.js b/lib/internal/test_runner/reporter/spec.js index 3637c74111c4b7..5bd3474971d276 100644 --- a/lib/internal/test_runner/reporter/spec.js +++ b/lib/internal/test_runner/reporter/spec.js @@ -10,7 +10,7 @@ const { SafeMap, StringPrototypeRepeat, } = primordials; -const assert = require('assert'); +const assert = require('internal/assert'); const Transform = require('internal/streams/transform'); const { inspectWithNoCustomRetry } = require('internal/errors'); const { green, blue, red, white, gray } = require('internal/util/colors'); diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index 5108fc3283f63b..78c50dd4b22343 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -12,7 +12,6 @@ const { ArrayPrototypeSplice, FunctionPrototypeCall, Number, - ObjectAssign, ObjectKeys, PromisePrototypeThen, SafePromiseAll, @@ -37,6 +36,7 @@ const { codes: { ERR_TEST_FAILURE, }, + setStackTraceLimit, } = require('internal/errors'); const { validateArray, validateBoolean, validateFunction } = require('internal/validators'); const { getInspectPort, isUsingInspector, isInspectorMessage } = require('internal/util/inspector'); @@ -314,14 +314,14 @@ function runTestFile(path, root, inspectPort, filesWatcher) { if (code !== 0 || signal !== null) { if (!err) { const failureType = subtest.failedSubtests ? kSubtestsFailed : kTestCodeFailure; - err = ObjectAssign(new ERR_TEST_FAILURE('test failed', failureType), { + const { stackTraceLimit } = Error; + setStackTraceLimit(0); + err = new ERR_TEST_FAILURE('test failed', failureType, { __proto__: null, exitCode: code, signal: signal, - // The stack will not be useful since the failures came from tests - // in a child process. - stack: undefined, }); + setStackTraceLimit(stackTraceLimit); } throw err; diff --git a/lib/internal/test_runner/utils.js b/lib/internal/test_runner/utils.js index 72270e464248a5..d34976b930329e 100644 --- a/lib/internal/test_runner/utils.js +++ b/lib/internal/test_runner/utils.js @@ -20,7 +20,6 @@ const { ERR_INVALID_ARG_VALUE, ERR_TEST_FAILURE, }, - kIsNodeError, } = require('internal/errors'); const { compose } = require('stream'); @@ -68,7 +67,7 @@ function createDeferredCallback() { } function isTestFailureError(err) { - return err?.code === 'ERR_TEST_FAILURE' && kIsNodeError in err; + return err instanceof ERR_TEST_FAILURE; } function convertStringToRegExp(str, name) { diff --git a/lib/internal/test_runner/yaml_to_js.js b/lib/internal/test_runner/yaml_to_js.js index 6eb193f4afd36e..21d0d62552e421 100644 --- a/lib/internal/test_runner/yaml_to_js.js +++ b/lib/internal/test_runner/yaml_to_js.js @@ -3,6 +3,7 @@ const { codes: { ERR_TEST_FAILURE, }, + setStackTraceLimit, } = require('internal/errors'); const AssertionError = require('internal/assert/assertion_error'); const { @@ -32,6 +33,8 @@ function reConstructError(parsedYaml) { const stack = parsedYaml.stack ? kStackDelimiter + ArrayPrototypeJoin(parsedYaml.stack, `\n${kStackDelimiter}`) : ''; let error, cause; + const { stackTraceLimit } = Error; + setStackTraceLimit(0); if (isAssertionError) { cause = new AssertionError({ message: parsedYaml.error, @@ -54,6 +57,7 @@ function reConstructError(parsedYaml) { error = new ERR_TEST_FAILURE(cause, parsedYaml.failureType); error.stack = stack; } + setStackTraceLimit(stackTraceLimit); parsedYaml.error = error ?? cause; delete parsedYaml.stack; diff --git a/lib/net.js b/lib/net.js index 7ac8a0bdc649c5..d4f3a5fa3f8377 100644 --- a/lib/net.js +++ b/lib/net.js @@ -101,7 +101,7 @@ const { ERR_SOCKET_CLOSED_BEFORE_CONNECTION, ERR_MISSING_ARGS, }, - aggregateErrors, + aggregateTwoErrors, errnoException, exceptionWithHostPort, genericNodeError, @@ -1092,7 +1092,7 @@ function internalConnectMultiple(context, canceled) { // All connections have been tried without success, destroy with error if (canceled || context.current === context.addresses.length) { - self.destroy(aggregateErrors(context.errors)); + self.destroy(context.error); return; } @@ -1118,7 +1118,10 @@ function internalConnectMultiple(context, canceled) { err = checkBindError(err, localPort, handle); if (err) { - ArrayPrototypePush(context.errors, exceptionWithHostPort(err, 'bind', localAddress, localPort)); + context.error = aggregateTwoErrors( + exceptionWithHostPort(err, 'bind', localAddress, localPort), + context.error, + ); internalConnectMultiple(context); return; } @@ -1149,7 +1152,10 @@ function internalConnectMultiple(context, canceled) { details = sockname.address + ':' + sockname.port; } - ArrayPrototypePush(context.errors, exceptionWithHostPort(err, 'connect', address, port, details)); + context.error = aggregateTwoErrors( + exceptionWithHostPort(err, 'connect', address, port, details), + context.error, + ); internalConnectMultiple(context); return; } @@ -1564,7 +1570,7 @@ function afterConnectMultiple(context, status, handle, req, readable, writable) ex.localPort = req.localPort; } - ArrayPrototypePush(context.errors, ex); + context.error = aggregateTwoErrors(ex, context.error); // Try the next address internalConnectMultiple(context, status === UV_ECANCELED); diff --git a/lib/repl.js b/lib/repl.js index 241e25f0f2095a..8e039746aafa2d 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -44,7 +44,6 @@ const { ArrayPrototypeFilter, - ArrayPrototypeFindIndex, ArrayPrototypeForEach, ArrayPrototypeIncludes, ArrayPrototypeJoin, @@ -52,12 +51,10 @@ const { ArrayPrototypePop, ArrayPrototypePush, ArrayPrototypePushApply, - ArrayPrototypeReverse, ArrayPrototypeShift, ArrayPrototypeSlice, ArrayPrototypeSome, ArrayPrototypeSort, - ArrayPrototypeSplice, ArrayPrototypeUnshift, Boolean, Error, @@ -143,7 +140,7 @@ const { ERR_INVALID_REPL_INPUT, ERR_SCRIPT_EXECUTION_INTERRUPTED, }, - isErrorStackTraceLimitWritable, + setStackTraceLimit, overrideStackTrace, } = require('internal/errors'); const { sendInspectorCommand } = require('internal/util/inspector'); @@ -601,10 +598,10 @@ function REPLServer(prompt, if (self.breakEvalOnSigint) { const interrupt = new Promise((resolve, reject) => { sigintListener = () => { - const tmp = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; + const { stackTraceLimit } = Error; + setStackTraceLimit(0); const err = new ERR_SCRIPT_EXECUTION_INTERRUPTED(); - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = tmp; + setStackTraceLimit(stackTraceLimit); reject(err); }; prioritizedSigintQueue.add(sigintListener); @@ -646,18 +643,17 @@ function REPLServer(prompt, if (typeof e === 'object' && e !== null) { overrideStackTrace.set(e, (error, stackFrames) => { - let frames; + let frames = stackFrames; if (typeof stackFrames === 'object') { // Search from the bottom of the call stack to // find the first frame with a null function name - const idx = ArrayPrototypeFindIndex( - ArrayPrototypeReverse(stackFrames), - (frame) => frame.getFunctionName() === null, + const idx = stackFrames.findLastIndex( + (frame, i) => frame.getFunctionName() === null, ); - // If found, get rid of it and everything below it - frames = ArrayPrototypeSplice(stackFrames, idx + 1); - } else { - frames = stackFrames; + if (idx !== -1) { + // If found, get rid of it and everything above it + frames = ArrayPrototypeSlice(stackFrames, 0, idx); + } } // FIXME(devsnek): this is inconsistent with the checks // that the real prepareStackTrace dispatch uses in @@ -665,8 +661,12 @@ function REPLServer(prompt, if (typeof Error.prepareStackTrace === 'function') { return Error.prepareStackTrace(error, frames); } - ArrayPrototypePush(frames, error); - return ArrayPrototypeJoin(ArrayPrototypeReverse(frames), '\n at '); + + if (frames.length === 0) { + return `${error}`; + } + + return `${error}\n at ${ArrayPrototypeJoin(frames, '\n at ')}`; }); decorateErrorStack(e); diff --git a/lib/stream.js b/lib/stream.js index 4c105067bae1ca..49b698d05ebbd7 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -59,7 +59,7 @@ for (const key of ObjectKeys(streamReturningOperators)) { const op = streamReturningOperators[key]; function fn(...args) { if (new.target) { - throw ERR_ILLEGAL_CONSTRUCTOR(); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } return Stream.Readable.from(ReflectApply(op, this, args)); } @@ -77,7 +77,7 @@ for (const key of ObjectKeys(promiseReturningOperators)) { const op = promiseReturningOperators[key]; function fn(...args) { if (new.target) { - throw ERR_ILLEGAL_CONSTRUCTOR(); + throw new ERR_ILLEGAL_CONSTRUCTOR(); } return ReflectApply(op, this, args); } diff --git a/test/message/internal_assert.out b/test/message/internal_assert.out index bd25c879478083..197b863bf6ae69 100644 --- a/test/message/internal_assert.out +++ b/test/message/internal_assert.out @@ -5,7 +5,6 @@ node:internal/assert:* Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals. Please open an issue with this stack trace at https://github.com/nodejs/node/issues - at new NodeError (node:internal/errors:*:*) at assert (node:internal/assert:*:*) at * (*test*message*internal_assert.js:7:1) at * diff --git a/test/message/internal_assert_fail.out b/test/message/internal_assert_fail.out index 408d6d3364470d..e6895691cda9c1 100644 --- a/test/message/internal_assert_fail.out +++ b/test/message/internal_assert_fail.out @@ -6,7 +6,6 @@ Error [ERR_INTERNAL_ASSERTION]: Unreachable! This is caused by either a bug in Node.js or incorrect usage of Node.js internals. Please open an issue with this stack trace at https://github.com/nodejs/node/issues - at new NodeError (node:internal/errors:*:*) at Function.fail (node:internal/assert:*:*) at * (*test*message*internal_assert_fail.js:7:8) at * diff --git a/test/message/util_inspect_error.js b/test/message/util_inspect_error.js index 20affd6c711fd8..164ed10d3996e6 100644 --- a/test/message/util_inspect_error.js +++ b/test/message/util_inspect_error.js @@ -10,3 +10,11 @@ console.log(util.inspect({ err, nested: { err } }, { compact: false })); err.foo = 'bar'; console.log(util.inspect(err, { compact: true, breakLength: 5 })); + +class Foo extends Error { + toString() { + return 1; + } +} + +console.log(new Foo()); diff --git a/test/message/util_inspect_error.out b/test/message/util_inspect_error.out index 644ccd58831ef7..dc320fe94e6b4e 100644 --- a/test/message/util_inspect_error.out +++ b/test/message/util_inspect_error.out @@ -51,3 +51,11 @@ bar at * at * foo: 'bar' } +Foo [Error] + at *util_inspect_error.js* + at * + at * + at * + at * + at * + at * diff --git a/test/parallel/test-buffer-readint.js b/test/parallel/test-buffer-readint.js index 8758652b28a4a4..fd083950cc1e39 100644 --- a/test/parallel/test-buffer-readint.js +++ b/test/parallel/test-buffer-readint.js @@ -2,6 +2,7 @@ require('../common'); const assert = require('assert'); +const { inspect } = require('util'); // Test OOB { @@ -178,7 +179,8 @@ const assert = require('assert'); code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "offset" is out of range. ' + - `It must be >= 0 and <= ${8 - i}. Received ${offset}` + `It must be >= 0 and <= ${8 - i}. Received ` + + inspect(offset, { numericSeparator: true }) }); }); diff --git a/test/parallel/test-buffer-readuint.js b/test/parallel/test-buffer-readuint.js index 31e32bc3df14db..e7b49318de0673 100644 --- a/test/parallel/test-buffer-readuint.js +++ b/test/parallel/test-buffer-readuint.js @@ -2,6 +2,7 @@ require('../common'); const assert = require('assert'); +const { inspect } = require('util'); // Test OOB { @@ -146,7 +147,8 @@ const assert = require('assert'); code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "offset" is out of range. ' + - `It must be >= 0 and <= ${8 - i}. Received ${offset}` + `It must be >= 0 and <= ${8 - i}. Received ` + + inspect(offset, { numericSeparator: true }) }); }); diff --git a/test/parallel/test-buffer-writeint.js b/test/parallel/test-buffer-writeint.js index e4b916b1cff27f..659de05a8c6c32 100644 --- a/test/parallel/test-buffer-writeint.js +++ b/test/parallel/test-buffer-writeint.js @@ -4,6 +4,7 @@ require('../common'); const assert = require('assert'); +const { inspect } = require('util'); const errorOutOfBounds = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', @@ -222,16 +223,14 @@ const errorOutOfBounds = { range = `>= -(2 ** ${i * 8 - 1}) and < 2 ** ${i * 8 - 1}`; } [min - 1, max + 1].forEach((val) => { - const received = i > 4 ? - String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : - val; assert.throws(() => { data[fn](val, 0, i); }, { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "value" is out of range. ' + - `It must be ${range}. Received ${received}` + `It must be ${range}. Received ` + + inspect(val, { numericSeparator: true }) }); }); @@ -251,7 +250,8 @@ const errorOutOfBounds = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "offset" is out of range. ' + - `It must be >= 0 and <= ${8 - i}. Received ${offset}` + `It must be >= 0 and <= ${8 - i}. Received ` + + inspect(offset, { numericSeparator: true }) }); }); diff --git a/test/parallel/test-buffer-writeuint.js b/test/parallel/test-buffer-writeuint.js index efacdb7ab48c3b..6260e080a6ae4a 100644 --- a/test/parallel/test-buffer-writeuint.js +++ b/test/parallel/test-buffer-writeuint.js @@ -1,6 +1,7 @@ 'use strict'; require('../common'); +const { inspect } = require('util'); const assert = require('assert'); // We need to check the following things: @@ -90,7 +91,8 @@ const assert = require('assert'); { code: 'ERR_OUT_OF_RANGE', message: 'The value of "value" is out of range. ' + - `It must be >= 0 and <= 65535. Received ${value}` + 'It must be >= 0 and <= 65535. Received ' + + inspect(value, { numericSeparator: true }) } ); }); @@ -170,9 +172,6 @@ const assert = require('assert'); // Test 1 to 6 bytes. for (let i = 1; i <= 6; i++) { const range = i < 5 ? `= ${val - 1}` : ` 2 ** ${i * 8}`; - const received = i > 4 ? - String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') : - val; ['writeUIntBE', 'writeUIntLE'].forEach((fn) => { assert.throws(() => { data[fn](val, 0, i); @@ -180,7 +179,8 @@ const assert = require('assert'); code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "value" is out of range. ' + - `It must be >= 0 and <${range}. Received ${received}` + `It must be >= 0 and <${range}. Received ` + + inspect(val, { numericSeparator: true }) }); ['', '0', null, {}, [], () => {}, true, false].forEach((o) => { @@ -199,7 +199,8 @@ const assert = require('assert'); code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "offset" is out of range. ' + - `It must be >= 0 and <= ${8 - i}. Received ${offset}` + `It must be >= 0 and <= ${8 - i}. Received ` + + inspect(offset, { numericSeparator: true }) }); }); diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index 1a77266b057041..29c5790890afa2 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -1147,7 +1147,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); message: 'The value of "options.modulusLength" is out of range. ' + 'It must be an integer. ' + - `Received ${inspect(modulusLength)}` + `Received ${inspect(modulusLength, { numericSeparator: true })}` }); } @@ -1273,7 +1273,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); message: 'The value of "options.divisorLength" is out of range. ' + 'It must be an integer. ' + - `Received ${inspect(divisorLength)}` + `Received ${inspect(divisorLength, { numericSeparator: true })}` }); } @@ -1288,7 +1288,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); message: 'The value of "options.divisorLength" is out of range. ' + 'It must be >= 0 && <= 2147483647. ' + - `Received ${inspect(divisorLength)}` + `Received ${inspect(divisorLength, { numericSeparator: true })}` }); } } @@ -1413,7 +1413,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); code: 'ERR_OUT_OF_RANGE', message: 'The value of "options.primeLength" is out of range. ' + 'It must be >= 0 && <= 2147483647. ' + - 'Received 2147483648', + 'Received 2_147_483_648', }); assert.throws(() => { @@ -1438,7 +1438,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); code: 'ERR_OUT_OF_RANGE', message: 'The value of "options.generator" is out of range. ' + 'It must be >= 0 && <= 2147483647. ' + - 'Received 2147483648', + 'Received 2_147_483_648', }); assert.throws(() => { @@ -1529,7 +1529,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); code: 'ERR_OUT_OF_RANGE', message: 'The value of "options.saltLength" is out of range. ' + 'It must be >= 0 && <= 2147483647. ' + - 'Received 2147483648' + 'Received 2_147_483_648' }); assert.throws(() => { diff --git a/test/parallel/test-crypto-random.js b/test/parallel/test-crypto-random.js index ceaa859a0e0316..e9e796462aa404 100644 --- a/test/parallel/test-crypto-random.js +++ b/test/parallel/test-crypto-random.js @@ -28,6 +28,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); +const { inspect } = require('util'); const { kMaxLength } = require('buffer'); const kMaxInt32 = 2 ** 31 - 1; @@ -54,7 +55,8 @@ common.expectWarning('DeprecationWarning', code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "size" is out of range. It must be >= 0 && <= ' + - `${kMaxPossibleLength}. Received ${value}` + `${kMaxPossibleLength}. Received ` + + inspect(value, { numericSeparator: true }) }; assert.throws(() => f(value), errObj); assert.throws(() => f(value, common.mustNotCall()), errObj); @@ -252,7 +254,8 @@ common.expectWarning('DeprecationWarning', code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "offset" is out of range. ' + - `It must be >= 0 && <= 10. Received ${offsetSize}` + 'It must be >= 0 && <= 10. Received ' + + inspect(offsetSize, { numericSeparator: true }) }; assert.throws(() => crypto.randomFillSync(buf, offsetSize), errObj); @@ -262,7 +265,8 @@ common.expectWarning('DeprecationWarning', errObj); errObj.message = 'The value of "size" is out of range. It must be >= ' + - `0 && <= ${kMaxPossibleLength}. Received ${offsetSize}`; + `0 && <= ${kMaxPossibleLength}. Received ` + + inspect(offsetSize, { numericSeparator: true }); assert.throws(() => crypto.randomFillSync(buf, 1, offsetSize), errObj); assert.throws( @@ -295,7 +299,8 @@ assert.throws( code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "size" is out of range. ' + - `It must be >= 0 && <= ${kMaxPossibleLength}. Received 4294967296` + `It must be >= 0 && <= ${kMaxPossibleLength}. ` + + 'Received 4_294_967_296' } ); diff --git a/test/parallel/test-errors-systemerror.js b/test/parallel/test-errors-systemerror.js index 38afbd4aa7d164..73f86a75c6db01 100644 --- a/test/parallel/test-errors-systemerror.js +++ b/test/parallel/test-errors-systemerror.js @@ -5,14 +5,6 @@ require('../common'); const assert = require('assert'); const { E, SystemError, codes } = require('internal/errors'); -assert.throws( - () => { new SystemError(); }, - { - name: 'TypeError', - message: "Cannot read properties of undefined (reading 'syscall')", - } -); - E('ERR_TEST', 'custom message', SystemError); const { ERR_TEST } = codes; diff --git a/test/parallel/test-fs-fchmod.js b/test/parallel/test-fs-fchmod.js index da37080ddeedd8..39c8a27dcfa5cb 100644 --- a/test/parallel/test-fs-fchmod.js +++ b/test/parallel/test-fs-fchmod.js @@ -2,6 +2,7 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); +const { inspect } = require('util'); // This test ensures that input for fchmod is valid, testing for valid // inputs for fd and mode @@ -35,8 +36,8 @@ assert.throws(() => fs.fchmod(1, '123x'), { const errObj = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', - message: 'The value of "fd" is out of range. It must be >= 0 && <= ' + - `2147483647. Received ${input}` + message: 'The value of "fd" is out of range. It must be >= 0 && <= 2' + + `147483647. Received ${inspect(input, { numericSeparator: true })}` }; assert.throws(() => fs.fchmod(input), errObj); assert.throws(() => fs.fchmodSync(input), errObj); @@ -46,8 +47,8 @@ assert.throws(() => fs.fchmod(1, '123x'), { const errObj = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', - message: 'The value of "mode" is out of range. It must be >= 0 && <= ' + - `4294967295. Received ${input}` + message: 'The value of "mode" is out of range. It must be >= 0 && <= 4' + + `294967295. Received ${inspect(input, { numericSeparator: true })}` }; assert.throws(() => fs.fchmod(1, input), errObj); diff --git a/test/parallel/test-fs-fchown.js b/test/parallel/test-fs-fchown.js index 03a9ef3780ae6b..b234e4634ea664 100644 --- a/test/parallel/test-fs-fchown.js +++ b/test/parallel/test-fs-fchown.js @@ -3,6 +3,7 @@ require('../common'); const assert = require('assert'); const fs = require('fs'); +const { inspect } = require('util'); function testFd(input, errObj) { assert.throws(() => fs.fchown(input), errObj); @@ -49,11 +50,13 @@ function testGid(input, errObj) { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "fd" is out of range. It must be ' + - `>= 0 && <= 2147483647. Received ${input}` + '>= 0 && <= 2147483647. Received ' + + inspect(input, { numericSeparator: true }) }; testFd(input, errObj); errObj.message = 'The value of "uid" is out of range. It must be >= -1 && ' + - `<= 4294967295. Received ${input}`; + '<= 4294967295. Received ' + + inspect(input, { numericSeparator: true }); testUid(input, errObj); errObj.message = errObj.message.replace('uid', 'gid'); testGid(input, errObj); diff --git a/test/parallel/test-fs-lchmod.js b/test/parallel/test-fs-lchmod.js index ae5cb3ba2a230a..b68c635ba50b3b 100644 --- a/test/parallel/test-fs-lchmod.js +++ b/test/parallel/test-fs-lchmod.js @@ -3,6 +3,7 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); +const { inspect } = require('util'); const { promises } = fs; const f = __filename; @@ -58,7 +59,8 @@ assert.throws(() => fs.lchmodSync(f, '123x'), { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "mode" is out of range. It must be >= 0 && <= ' + - `4294967295. Received ${input}` + '4294967295. Received ' + + inspect(input, { numericSeparator: true }) }; assert.rejects(promises.lchmod(f, input, () => {}), errObj); diff --git a/test/parallel/test-fs-write-buffer-large.js b/test/parallel/test-fs-write-buffer-large.js index a80072354eaa0f..920835c27cd9a1 100644 --- a/test/parallel/test-fs-write-buffer-large.js +++ b/test/parallel/test-fs-write-buffer-large.js @@ -33,7 +33,7 @@ fs.open(filename, 'w', 0o644, common.mustSucceed((fd) => { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "length" is out of range. ' + - 'It must be >= 0 && <= 2147483647. Received 2147483648' + 'It must be >= 0 && <= 2147483647. Received 2_147_483_648' }); fs.closeSync(fd); diff --git a/test/parallel/test-http2-altsvc.js b/test/parallel/test-http2-altsvc.js index c5abfc33265330..6d46dfc711d949 100644 --- a/test/parallel/test-http2-altsvc.js +++ b/test/parallel/test-http2-altsvc.js @@ -6,6 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const http2 = require('http2'); +const { inspect } = require('util'); const Countdown = require('../common/countdown'); const server = http2.createServer(); @@ -34,7 +35,8 @@ server.on('session', common.mustCall((session) => { code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "originOrStream" is out of ' + - `range. It must be > 0 && < 4294967296. Received ${input}` + 'range. It must be > 0 && < 4294967296. Received ' + + inspect(input, { numericSeparator: true }) } ); }); diff --git a/test/parallel/test-http2-client-rststream-before-connect.js b/test/parallel/test-http2-client-rststream-before-connect.js index bc0cb5ff619dc0..6184baf8641bf3 100644 --- a/test/parallel/test-http2-client-rststream-before-connect.js +++ b/test/parallel/test-http2-client-rststream-before-connect.js @@ -24,7 +24,7 @@ server.listen(0, common.mustCall(() => { name: 'RangeError', code: 'ERR_OUT_OF_RANGE', message: 'The value of "code" is out of range. It must be ' + - '>= 0 && <= 4294967295. Received 4294967296' + '>= 0 && <= 4294967295. Received 4_294_967_296' } ); assert.strictEqual(req.closed, false); diff --git a/test/parallel/test-http2-client-setLocalWindowSize.js b/test/parallel/test-http2-client-setLocalWindowSize.js index 8e3b57ed0c1a6b..04501894dc651d 100644 --- a/test/parallel/test-http2-client-setLocalWindowSize.js +++ b/test/parallel/test-http2-client-setLocalWindowSize.js @@ -6,6 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const http2 = require('http2'); +const { inspect } = require('util'); { const server = http2.createServer(); @@ -34,7 +35,8 @@ const http2 = require('http2'); name: 'RangeError', code: 'ERR_OUT_OF_RANGE', message: 'The value of "windowSize" is out of range.' + - ' It must be >= 0 && <= 2147483647. Received ' + outOfRangeNum + ' It must be >= 0 && <= 2147483647. Received ' + + inspect(outOfRangeNum, { numericSeparator: true }) } ); diff --git a/test/parallel/test-http2-client-setNextStreamID-errors.js b/test/parallel/test-http2-client-setNextStreamID-errors.js index aace5845252af6..948e0645dd7dd8 100644 --- a/test/parallel/test-http2-client-setNextStreamID-errors.js +++ b/test/parallel/test-http2-client-setNextStreamID-errors.js @@ -6,6 +6,7 @@ if (!common.hasCrypto) const assert = require('assert'); const http2 = require('http2'); +const { inspect } = require('util'); const server = http2.createServer(); server.on('stream', (stream) => { @@ -34,7 +35,8 @@ server.listen(0, common.mustCall(() => { name: 'RangeError', code: 'ERR_OUT_OF_RANGE', message: 'The value of "id" is out of range.' + - ' It must be > 0 and <= 4294967295. Received ' + outOfRangeNum + ' It must be > 0 and <= 4294967295. Received ' + + inspect(outOfRangeNum, { numericSeparator: true }) } ); diff --git a/test/parallel/test-http2-invalidargtypes-errors.js b/test/parallel/test-http2-invalidargtypes-errors.js index 5f126b060a9f49..00077142823cce 100644 --- a/test/parallel/test-http2-invalidargtypes-errors.js +++ b/test/parallel/test-http2-invalidargtypes-errors.js @@ -5,6 +5,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const http2 = require('http2'); +const { inspect } = require('util'); const server = http2.createServer(); @@ -35,7 +36,7 @@ server.on('stream', common.mustCall((stream) => { name: 'RangeError', message: 'The value of "code" is out of range. ' + 'It must be >= 0 && <= 4294967295. ' + - `Received ${code}` + `Received ${inspect(code, { numericSeparator: true })}` } ); }); diff --git a/test/parallel/test-inspector-open-port-integer-overflow.js b/test/parallel/test-inspector-open-port-integer-overflow.js index 0f9a4799d0642a..e9061a5d6cfe94 100644 --- a/test/parallel/test-inspector-open-port-integer-overflow.js +++ b/test/parallel/test-inspector-open-port-integer-overflow.js @@ -13,5 +13,5 @@ const inspector = require('inspector'); assert.throws(() => inspector.open(99999), { name: 'RangeError', code: 'ERR_OUT_OF_RANGE', - message: 'The value of "port" is out of range. It must be >= 0 && <= 65535. Received 99999' + message: 'The value of "port" is out of range. It must be >= 0 && <= 65535. Received 99_999' }); diff --git a/test/parallel/test-repl-pretty-custom-stack.js b/test/parallel/test-repl-pretty-custom-stack.js index a10cd032a688c4..59171e45005491 100644 --- a/test/parallel/test-repl-pretty-custom-stack.js +++ b/test/parallel/test-repl-pretty-custom-stack.js @@ -42,8 +42,8 @@ const origPrepareStackTrace = Error.prepareStackTrace; Error.prepareStackTrace = (err, stack) => { if (err instanceof SyntaxError) return err.toString(); - stack.push(err); - return stack.reverse().join('--->\n'); + stack.unshift(err); + return stack.join('--->\n'); }; process.on('uncaughtException', (e) => { diff --git a/test/parallel/test-repl-top-level-await.js b/test/parallel/test-repl-top-level-await.js index 1abcca75f1e2a0..44b5d25d807010 100644 --- a/test/parallel/test-repl-top-level-await.js +++ b/test/parallel/test-repl-top-level-await.js @@ -204,13 +204,12 @@ async function ctrlCTest() { 'await new Promise(() => {})', { ctrl: true, name: 'c' }, ]); - assert.deepStrictEqual(output.slice(0, 3), [ + assert.deepStrictEqual(output, [ 'await new Promise(() => {})\r', 'Uncaught:', - 'Error [ERR_SCRIPT_EXECUTION_INTERRUPTED]: ' + - 'Script execution was interrupted by `SIGINT`', - ]); - assert.deepStrictEqual(output.slice(-2), [ + '[Error [ERR_SCRIPT_EXECUTION_INTERRUPTED]: ' + + 'Script execution was interrupted by `SIGINT`] {', + " code: 'ERR_SCRIPT_EXECUTION_INTERRUPTED'", '}', PROMPT, ]); diff --git a/test/parallel/test-streams-highwatermark.js b/test/parallel/test-streams-highwatermark.js index 7018c5bf29ce08..50dc0e33237906 100644 --- a/test/parallel/test-streams-highwatermark.js +++ b/test/parallel/test-streams-highwatermark.js @@ -81,7 +81,7 @@ const { inspect } = require('util'); assert.throws(() => readable.read(hwm), common.expectsError({ code: 'ERR_OUT_OF_RANGE', message: 'The value of "size" is out of range.' + - ' It must be <= 1GiB. Received ' + - hwm, + ' It must be <= 1073741824. Received ' + + inspect(hwm, { numericSeparator: true }), })); } diff --git a/test/parallel/test-zlib-flush-flags.js b/test/parallel/test-zlib-flush-flags.js index 3d8e609adb6269..5c2652ca97598b 100644 --- a/test/parallel/test-zlib-flush-flags.js +++ b/test/parallel/test-zlib-flush-flags.js @@ -21,7 +21,7 @@ assert.throws( code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "options.flush" is out of range. It must ' + - 'be >= 0 and <= 5. Received 10000' + 'be >= 0 and <= 5. Received 10_000' } ); @@ -43,6 +43,6 @@ assert.throws( code: 'ERR_OUT_OF_RANGE', name: 'RangeError', message: 'The value of "options.finishFlush" is out of range. It must ' + - 'be >= 0 and <= 5. Received 10000' + 'be >= 0 and <= 5. Received 10_000' } );