From 0161353e7559d26e1ebff0ee26273cb8ab100375 Mon Sep 17 00:00:00 2001 From: Mohammed Keyvanzadeh Date: Mon, 24 Jan 2022 19:39:16 +0330 Subject: [PATCH 1/2] lib: replace validator and error Refs: https://github.com/nodejs/node/pull/41660 --- doc/api/crypto.md | 65 ++++++ doc/api/deprecations.md | 17 ++ doc/api/dns.md | 90 +++++++ doc/api/errors.md | 6 - doc/api/fs.md | 220 +++++++++++++++++- doc/api/http2.md | 57 ++++- doc/api/inspector.md | 6 + doc/api/net.md | 6 + doc/api/perf_hooks.md | 6 + doc/api/process.md | 5 + doc/api/readline.md | 20 ++ doc/api/stream.md | 5 + doc/api/timers.md | 18 ++ doc/api/tls.md | 6 + doc/api/url.md | 9 + lib/_tls_wrap.js | 3 +- lib/dns.js | 8 +- lib/fs.js | 7 +- lib/inspector.js | 4 +- lib/internal/crypto/diffiehellman.js | 6 +- lib/internal/crypto/hkdf.js | 4 +- lib/internal/crypto/keygen.js | 6 +- lib/internal/crypto/pbkdf2.js | 4 +- lib/internal/crypto/random.js | 12 +- lib/internal/crypto/scrypt.js | 4 +- lib/internal/crypto/sig.js | 6 +- lib/internal/errors.js | 7 +- lib/internal/fs/dir.js | 8 +- lib/internal/http2/compat.js | 4 +- lib/internal/http2/core.js | 14 +- lib/internal/perf/observe.js | 4 +- lib/internal/perf/timerify.js | 2 +- lib/internal/process/task_queues.js | 3 +- lib/internal/readline/callbacks.js | 10 +- lib/internal/stream_base_commons.js | 6 +- lib/internal/streams/pipeline.js | 4 +- lib/internal/timers.js | 4 +- lib/internal/url.js | 4 +- lib/internal/validators.js | 23 +- lib/timers.js | 8 +- test/parallel/test-crypto-keygen.js | 5 +- test/parallel/test-crypto-pbkdf2.js | 2 +- test/parallel/test-crypto-prime.js | 2 +- test/parallel/test-crypto-random.js | 10 +- test/parallel/test-crypto-scrypt.js | 2 +- test/parallel/test-crypto-secret-keygen.js | 2 +- test/parallel/test-dns-lookup.js | 4 +- test/parallel/test-dns-resolvens-typeerror.js | 2 +- test/parallel/test-dns.js | 6 +- test/parallel/test-fs-access.js | 4 +- test/parallel/test-fs-append-file.js | 2 +- test/parallel/test-fs-close-errors.js | 2 +- test/parallel/test-fs-copyfile.js | 2 +- test/parallel/test-fs-exists.js | 6 +- test/parallel/test-fs-lchmod.js | 6 +- test/parallel/test-fs-lchown.js | 2 +- test/parallel/test-fs-make-callback.js | 2 +- test/parallel/test-fs-makeStatsCallback.js | 2 +- test/parallel/test-fs-open.js | 2 +- test/parallel/test-fs-opendir.js | 6 +- test/parallel/test-fs-read.js | 3 +- ...t-http2-client-rststream-before-connect.js | 4 +- ...st-http2-client-settings-before-connect.js | 5 +- ...ompat-serverresponse-createpushresponse.js | 3 +- test/parallel/test-http2-ping.js | 5 +- ...st-http2-server-push-stream-errors-args.js | 3 +- ...est-http2-server-settimeout-no-callback.js | 5 +- test/parallel/test-http2-timeouts.js | 6 +- test/parallel/test-inspector-module.js | 4 +- test/parallel/test-net-socket-timeout.js | 5 +- test/parallel/test-next-tick-errors.js | 2 +- test/parallel/test-performanceobserver.js | 4 +- test/parallel/test-process-next-tick.js | 4 +- test/parallel/test-readline-csi.js | 8 +- test/parallel/test-stream-pipeline.js | 4 +- test/parallel/test-timers-refresh.js | 4 +- .../test-timers-throw-when-cb-not-function.js | 2 +- .../test-tls-disable-renegotiation.js | 4 +- .../test-whatwg-url-custom-searchparams.js | 2 +- 79 files changed, 667 insertions(+), 182 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 6d1fc3a5672ff8..2cd56b8f579739 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -2869,6 +2869,12 @@ This property is deprecated. Please use `crypto.setFips()` and * `candidate` {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} @@ -3547,6 +3553,12 @@ Both keys must have the same `asymmetricKeyType`, which must be one of `'dh'` * `type`: {string} The intended use of the generated secret key. Currently @@ -3592,6 +3604,11 @@ generateKey('hmac', { length: 64 }, (err, key) => { * `size` {number} The size (in bits) of the prime to generate. @@ -4118,6 +4141,12 @@ A convenient alias for [`crypto.webcrypto.getRandomValues()`][]. * `digest` {string} The digest algorithm to use. @@ -4221,6 +4250,11 @@ console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653' * `min` {integer} Start of random range (inclusive). **Default:** `0`. @@ -5021,6 +5071,11 @@ cryptographic pseudorandom number generator. + +Type: End-of-Life + +This error was removed due to adding more confusion to +the errors used for value type validation. + +Use [`ERR_INVALID_ARG_TYPE`][] instead. + [Legacy URL API]: url.md#legacy-url-api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 @@ -3070,6 +3086,7 @@ Use [`buffer.subarray`][] which does the same thing instead. [`Buffer.isBuffer()`]: buffer.md#static-method-bufferisbufferobj [`Cipher`]: crypto.md#class-cipher [`Decipher`]: crypto.md#class-decipher +[`ERR_INVALID_ARG_TYPE`]: errors.md#err_invalid_arg_type [`REPLServer.clearBufferedCommand()`]: repl.md#replserverclearbufferedcommand [`ReadStream.open()`]: fs.md#class-fsreadstream [`Server.getConnections()`]: net.md#servergetconnectionscallback diff --git a/doc/api/dns.md b/doc/api/dns.md index c1089f2b244e28..e5a1b5e3ff82c6 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -179,6 +179,11 @@ section if a custom port is used. * `address` {string} @@ -315,6 +326,12 @@ If this method is invoked as its [`util.promisify()`][]ed version, it returns a * `hostname` {string} Host name to resolve. @@ -351,6 +368,11 @@ On error, `err` is an [`Error`][] object, where `err.code` is one of the + * `hostname` {string} * `callback` {Function} * `err` {Error} @@ -451,6 +487,12 @@ queries. It may be better to call individual methods like [`dns.resolve4()`][], * `hostname` {string} @@ -469,6 +511,12 @@ will contain an array of canonical name records available for the `hostname` added: - v15.0.0 - v14.17.0 +changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/41678 + description: Passing an invalid callback to the `callback` argument + now throws `ERR_INVALID_ARG_TYPE` instead of + `ERR_INVALID_CALLBACK`. --> * `hostname` {string} @@ -486,6 +534,12 @@ available for the `hostname` (e.g. `[{critical: 0, iodef: * `hostname` {string} @@ -502,6 +556,12 @@ property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`). * `hostname` {string} @@ -537,6 +597,12 @@ function will contain an array of objects with the following properties: * `hostname` {string} @@ -553,6 +619,12 @@ contain an array of name server records available for `hostname` * `hostname` {string} @@ -568,6 +640,12 @@ be an array of strings containing the reply records. * `hostname` {string} @@ -605,6 +683,12 @@ be an object with the following properties: * `hostname` {string} @@ -636,6 +720,12 @@ be an array of objects with the following properties: diff --git a/doc/api/errors.md b/doc/api/errors.md index 37e0e9f922bbda..da08930f4a401b 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1833,12 +1833,6 @@ less than -1 should never happen. A swap was performed on a `Buffer` but its size was not compatible with the operation. - - -### `ERR_INVALID_CALLBACK` - -A callback function was required but was not been provided to a Node.js API. - ### `ERR_INVALID_CHAR` diff --git a/doc/api/fs.md b/doc/api/fs.md index 0bf5e115687fee..f0a9c9291e0603 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1597,6 +1597,11 @@ concurrent modifications on the same file or data corruption may occur. > Stability: 1 - Experimental @@ -2307,6 +2343,11 @@ If `options` is a string, then it specifies the encoding. added: v0.0.2 deprecated: v1.0.0 changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/41678 + description: Passing an invalid callback to the `callback` argument + now throws `ERR_INVALID_ARG_TYPE` instead of + `ERR_INVALID_CALLBACK`. - version: v7.6.0 pr-url: https://github.com/nodejs/node/pull/10739 description: The `path` parameter can be a WHATWG `URL` object using @@ -2452,6 +2493,11 @@ process. * `path` {string|Buffer|URL} @@ -2753,6 +2845,11 @@ callback. * `fd` {integer} @@ -3374,6 +3522,11 @@ a promise for an `Object` with `bytesRead` and `buffers` properties. * `path` {string|Buffer|URL} @@ -3464,6 +3623,11 @@ this restriction. * `fd` {integer} @@ -5647,6 +5857,12 @@ closed. * `callback` {Function} diff --git a/doc/api/http2.md b/doc/api/http2.md index 6932742ca7d944..5b50edda674a58 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -496,6 +496,12 @@ frames have been acknowledged. * `payload` {Buffer|TypedArray|DataView} Optional ping payload. @@ -581,6 +587,12 @@ server.on('connect', (session) => { * `msecs` {number} @@ -644,6 +656,12 @@ An object describing the current status of this `Http2Session`. * `settings` {HTTP/2 Settings Object} @@ -1166,6 +1184,12 @@ See [`net.Socket.bufferSize`][] for details. * `code` {number} Unsigned 32-bit integer identifying the error code. @@ -1311,6 +1335,12 @@ value will be `undefined` after the `Http2Stream` instance is destroyed. * `msecs` {number} @@ -1506,6 +1536,12 @@ accepts push streams, `false` otherwise. Settings are the same for every * `headers` {HTTP/2 Headers Object} @@ -1985,6 +2021,11 @@ closed, although the server has already stopped allowing new sessions. See * `msecs` {number} **Default:** `120000` (2 minutes) @@ -2217,7 +2264,7 @@ on the `Http2SecureServer` after `msecs` milliseconds. The given callback is registered as a listener on the `'timeout'` event. -In case if `callback` is not a function, a new `ERR_INVALID_CALLBACK` +In case if `callback` is not a function, a new `ERR_INVALID_ARG_TYPE` error will be thrown. #### `server.timeout` @@ -3497,6 +3544,12 @@ See [`response.socket`][]. * `headers` {HTTP/2 Headers Object} An object describing the headers diff --git a/doc/api/inspector.md b/doc/api/inspector.md index 9dcd7431b29e9b..ea31db782d0b0f 100644 --- a/doc/api/inspector.md +++ b/doc/api/inspector.md @@ -169,6 +169,12 @@ enabled agents or configured breakpoints. * `method` {string} diff --git a/doc/api/net.md b/doc/api/net.md index f8bcb8dfc9db2e..99864eeb9fa2a2 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -1136,6 +1136,12 @@ algorithm. * `timeout` {number} diff --git a/doc/api/perf_hooks.md b/doc/api/perf_hooks.md index fd7c2bbcd68729..37d0d628cfddbe 100644 --- a/doc/api/perf_hooks.md +++ b/doc/api/perf_hooks.md @@ -568,6 +568,12 @@ initialized. * `callback` {Function} diff --git a/doc/api/process.md b/doc/api/process.md index 61d48dfb1d61f8..a3bd6563ded757 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -2353,6 +2353,11 @@ console.log(memoryUsage.rss()); * `callback` {Function} The function to call at the end of this turn of @@ -197,6 +203,12 @@ This method has a custom variant for promises that is available using * `callback` {Function} The function to call when the timer elapses. @@ -219,6 +231,12 @@ This method has a custom variant for promises that is available using * `callback` {Function} The function to call when the timer elapses. diff --git a/doc/api/tls.md b/doc/api/tls.md index c0412cf1eafbb5..f7aeee4c0e2b41 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1404,6 +1404,12 @@ Returns the numeric representation of the remote port. For example, `443`. * `options` {Object} diff --git a/doc/api/url.md b/doc/api/url.md index 1dbf336d66f319..3fa589397f77d6 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -851,6 +851,15 @@ Alias for [`urlSearchParams[@@iterator]()`][`urlSearchParams@@iterator()`]. #### `urlSearchParams.forEach(fn[, thisArg])` + + * `fn` {Function} Invoked for each name-value pair in the query * `thisArg` {Object} To be used as `this` value for when `fn` is called diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 57399c602a10bb..cb91d57c16ddd0 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -86,7 +86,6 @@ const { const { validateBoolean, validateBuffer, - validateCallback, validateFunction, validateInt32, validateNumber, @@ -826,7 +825,7 @@ TLSSocket.prototype._init = function(socket, wrap) { TLSSocket.prototype.renegotiate = function(options, callback) { validateObject(options, 'options'); if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } debug('%s renegotiate()', diff --git a/lib/dns.js b/lib/dns.js index 58492be9ba288a..d795e8e09045c4 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -51,7 +51,7 @@ const { ERR_MISSING_ARGS, } = errors.codes; const { - validateCallback, + validateFunction, validatePort, validateString, validateOneOf, @@ -110,7 +110,7 @@ function lookup(hostname, options, callback) { callback = options; family = 0; } else { - validateCallback(callback); + validateFunction(callback, 'callback'); if (options !== null && typeof options === 'object') { if (options.hints != null && typeof options.hints !== 'number') { @@ -200,7 +200,7 @@ function lookupService(address, port, callback) { validatePort(port); - validateCallback(callback); + validateFunction(callback, 'callback'); port = +port; @@ -239,7 +239,7 @@ function resolver(bindingName) { } validateString(name, 'name'); - validateCallback(callback); + validateFunction(callback, 'callback'); const req = new QueryReqWrap(); req.bindingName = bindingName; diff --git a/lib/fs.js b/lib/fs.js index 3f99d6b7b74739..b1300d0a7095e6 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -132,7 +132,6 @@ const { parseFileMode, validateBoolean, validateBuffer, - validateCallback, validateEncoding, validateFunction, validateInteger, @@ -174,7 +173,7 @@ function showTruncateDeprecation() { } function maybeCallback(cb) { - validateCallback(cb); + validateFunction(cb, 'cb'); return cb; } @@ -183,7 +182,7 @@ function maybeCallback(cb) { // for callbacks that are passed to the binding layer, callbacks that are // invoked from JS already run in the proper scope. function makeCallback(cb) { - validateCallback(cb); + validateFunction(cb, 'cb'); return (...args) => ReflectApply(cb, this, args); } @@ -192,7 +191,7 @@ function makeCallback(cb) { // an optimization, since the data passed back to the callback needs to be // transformed anyway. function makeStatsCallback(cb) { - validateCallback(cb); + validateFunction(cb, 'cb'); return (err, stats) => { if (err) return cb(err); diff --git a/lib/inspector.js b/lib/inspector.js index 46779a0ec21dac..58d8dbe45c7213 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -25,7 +25,7 @@ if (!hasInspector) const EventEmitter = require('events'); const { queueMicrotask } = require('internal/process/task_queues'); const { - validateCallback, + validateFunction, validateObject, validateString, } = require('internal/validators'); @@ -119,7 +119,7 @@ class Session extends EventEmitter { validateObject(params, 'params'); } if (callback) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (!this[connectionSymbol]) { diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index 2efdbdd5bac9d3..598db4052b976c 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -35,7 +35,7 @@ const { } = require('internal/errors'); const { - validateCallback, + validateFunction, validateInt32, validateObject, validateString, @@ -334,7 +334,7 @@ function deriveBitsECDH(name, publicKey, privateKey, callback) { validateString(name, 'name'); validateObject(publicKey, 'publicKey'); validateObject(privateKey, 'privateKey'); - validateCallback(callback); + validateFunction(callback, 'callback'); const job = new ECDHBitsJob(kCryptoJobAsync, name, publicKey, privateKey); job.ondone = (error, bits) => { if (error) return FunctionPrototypeCall(callback, job, error); @@ -348,7 +348,7 @@ function deriveBitsECDH(name, publicKey, privateKey, callback) { function deriveBitsDH(publicKey, privateKey, callback) { validateObject(publicKey, 'publicKey'); validateObject(privateKey, 'privateKey'); - validateCallback(callback); + validateFunction(callback, 'callback'); const job = new DHBitsJob(kCryptoJobAsync, publicKey, privateKey); job.ondone = (error, bits) => { if (error) return FunctionPrototypeCall(callback, job, error); diff --git a/lib/internal/crypto/hkdf.js b/lib/internal/crypto/hkdf.js index 1d8251a9245b66..fd274caf0b80ce 100644 --- a/lib/internal/crypto/hkdf.js +++ b/lib/internal/crypto/hkdf.js @@ -13,7 +13,7 @@ const { } = internalBinding('crypto'); const { - validateCallback, + validateFunction, validateInteger, validateString, validateUint32, @@ -115,7 +115,7 @@ function hkdf(hash, key, salt, info, length, callback) { length, } = validateParameters(hash, key, salt, info, length)); - validateCallback(callback); + validateFunction(callback, 'callback'); const job = new HKDFJob(kCryptoJobAsync, hash, key, salt, info, length); diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js index 1469a01682edda..bbbe72475bd870 100644 --- a/lib/internal/crypto/keygen.js +++ b/lib/internal/crypto/keygen.js @@ -43,7 +43,7 @@ const { customPromisifyArgs } = require('internal/util'); const { isInt32, isUint32, - validateCallback, + validateFunction, validateString, validateInteger, validateObject, @@ -76,7 +76,7 @@ function generateKeyPair(type, options, callback) { callback = options; options = undefined; } - validateCallback(callback); + validateFunction(callback, 'callback'); const job = createJob(kCryptoJobAsync, type, options); @@ -388,7 +388,7 @@ function generateKey(type, options, callback) { options = undefined; } - validateCallback(callback); + validateFunction(callback, 'callback'); const job = generateKeyJob(kCryptoJobAsync, type, options); diff --git a/lib/internal/crypto/pbkdf2.js b/lib/internal/crypto/pbkdf2.js index 753c4f2d9da597..b3a6303136f506 100644 --- a/lib/internal/crypto/pbkdf2.js +++ b/lib/internal/crypto/pbkdf2.js @@ -14,7 +14,7 @@ const { } = internalBinding('crypto'); const { - validateCallback, + validateFunction, validateInteger, validateString, validateUint32, @@ -42,7 +42,7 @@ function pbkdf2(password, salt, iterations, keylen, digest, callback) { ({ password, salt, iterations, keylen, digest } = check(password, salt, iterations, keylen, digest)); - validateCallback(callback); + validateFunction(callback, 'callback'); const job = new PBKDF2Job( kCryptoJobAsync, diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index 1423ea4295443e..fc2e19e501c405 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -42,7 +42,7 @@ const { const { validateNumber, validateBoolean, - validateCallback, + validateFunction, validateObject, validateUint32, } = require('internal/validators'); @@ -91,7 +91,7 @@ function assertSize(size, elementSize, offset, length) { function randomBytes(size, callback) { size = assertSize(size, 1, 0, Infinity); if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } const buf = new FastBuffer(size); @@ -161,7 +161,7 @@ function randomFill(buf, offset, size, callback) { callback = size; size = buf.length - offset; } else { - validateCallback(callback); + validateFunction(callback, 'callback'); } offset = assertOffset(offset, elementSize, buf.byteLength); @@ -214,7 +214,7 @@ function randomInt(min, max, callback) { const isSync = typeof callback === 'undefined'; if (!isSync) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (!NumberIsSafeInteger(min)) { throw new ERR_INVALID_ARG_TYPE('min', 'a safe integer', min); @@ -465,7 +465,7 @@ function generatePrime(size, options, callback) { callback = options; options = {}; } - validateCallback(callback); + validateFunction(callback, 'callback'); const job = createRandomPrimeJob(kCryptoJobAsync, size, options); job.ondone = (err, prime) => { @@ -525,7 +525,7 @@ function checkPrime(candidate, options = {}, callback) { callback = options; options = {}; } - validateCallback(callback); + validateFunction(callback, 'callback'); validateObject(options, 'options'); const { checks = 0, diff --git a/lib/internal/crypto/scrypt.js b/lib/internal/crypto/scrypt.js index 49e5b0624e1ae7..0d0ac1f7261e63 100644 --- a/lib/internal/crypto/scrypt.js +++ b/lib/internal/crypto/scrypt.js @@ -14,7 +14,7 @@ const { } = internalBinding('crypto'); const { - validateCallback, + validateFunction, validateInteger, validateInt32, validateUint32, @@ -54,7 +54,7 @@ function scrypt(password, salt, keylen, options, callback = defaults) { const { N, r, p, maxmem } = options; ({ password, salt, keylen } = options); - validateCallback(callback); + validateFunction(callback, 'callback'); const job = new ScryptJob( kCryptoJobAsync, password, salt, N, r, p, maxmem, keylen); diff --git a/lib/internal/crypto/sig.js b/lib/internal/crypto/sig.js index a204f35e60a15b..f68606c8655163 100644 --- a/lib/internal/crypto/sig.js +++ b/lib/internal/crypto/sig.js @@ -15,7 +15,7 @@ const { } = require('internal/errors'); const { - validateCallback, + validateFunction, validateEncoding, validateString, } = require('internal/validators'); @@ -143,7 +143,7 @@ function signOneShot(algorithm, data, key, callback) { validateString(algorithm, 'algorithm'); if (callback !== undefined) - validateCallback(callback); + validateFunction(callback, 'callback'); data = getArrayBufferOrView(data, 'data'); @@ -236,7 +236,7 @@ function verifyOneShot(algorithm, data, key, signature, callback) { validateString(algorithm, 'algorithm'); if (callback !== undefined) - validateCallback(callback); + validateFunction(callback, 'callback'); data = getArrayBufferOrView(data, 'data'); diff --git a/lib/internal/errors.js b/lib/internal/errors.js index c5b8146b851bf0..3b5d0d8e432cf9 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1208,7 +1208,10 @@ E('ERR_INVALID_ARG_TYPE', if (actual == null) { msg += `. Received ${actual}`; } else if (typeof actual === 'function' && actual.name) { - msg += `. Received function ${actual.name}`; + const inspected = lazyInternalUtilInspect() + .inspect(actual); + msg += `. Received ${inspected.startsWith('[class') ? + 'class' : 'function'} ${actual.name}`; } else if (typeof actual === 'object') { if (actual.constructor && actual.constructor.name) { msg += `. Received an instance of ${actual.constructor.name}`; @@ -1237,8 +1240,6 @@ E('ERR_INVALID_ARG_VALUE', (name, value, reason = 'is invalid') => { E('ERR_INVALID_ASYNC_ID', 'Invalid %s value: %s', RangeError); E('ERR_INVALID_BUFFER_SIZE', 'Buffer size must be a multiple of %s', RangeError); -E('ERR_INVALID_CALLBACK', - 'Callback must be a function. Received %O', TypeError); E('ERR_INVALID_CHAR', // Using a default argument here is important so the argument is not counted // towards `Function#length`. diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 917319661a647d..5fda9d8a7f3ef4 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -31,7 +31,7 @@ const { handleErrorFromBinding } = require('internal/fs/utils'); const { - validateCallback, + validateFunction, validateUint32 } = require('internal/validators'); @@ -89,7 +89,7 @@ class Dir { return this[kDirReadPromisified](); } - validateCallback(callback); + validateFunction(callback, 'callback'); if (this[kDirOperationQueue] !== null) { ArrayPrototypePush(this[kDirOperationQueue], () => { @@ -174,7 +174,7 @@ class Dir { } // callback - validateCallback(callback); + validateFunction(callback, 'callback'); if (this[kDirClosed] === true) { process.nextTick(callback, new ERR_DIR_CLOSED()); @@ -234,7 +234,7 @@ ObjectDefineProperty(Dir.prototype, SymbolAsyncIterator, { function opendir(path, options, callback) { callback = typeof options === 'function' ? options : callback; - validateCallback(callback); + validateFunction(callback, 'callback'); path = getValidatedPath(path); options = getOptions(options, { diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index 0c4519dfff5986..596167990cd022 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -53,7 +53,7 @@ const { hideStackFrames } = require('internal/errors'); const { - validateCallback, + validateFunction, validateString, } = require('internal/validators'); const { @@ -798,7 +798,7 @@ class Http2ServerResponse extends Stream { } createPushResponse(headers, callback) { - validateCallback(callback); + validateFunction(callback, 'callback'); if (this[kState].closed) { process.nextTick(callback, new ERR_HTTP2_INVALID_STREAM()); return; diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 0960bcc5e63e40..b7663cbb618f7d 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -120,7 +120,7 @@ const { } = require('internal/errors'); const { isUint32, - validateCallback, + validateFunction, validateInt32, validateInteger, validateNumber, @@ -1374,7 +1374,7 @@ class Http2Session extends EventEmitter { if (payload && payload.length !== 8) { throw new ERR_HTTP2_PING_LENGTH(); } - validateCallback(callback); + validateFunction(callback, 'callback'); const cb = pingCallback(callback); if (this.connecting || this.closed) { @@ -1472,7 +1472,7 @@ class Http2Session extends EventEmitter { validateSettings(settings); if (callback) { - validateCallback(callback); + validateFunction(callback, 'callback'); } debugSessionObj(this, 'sending settings'); @@ -2275,7 +2275,7 @@ class Http2Stream extends Duplex { validateInteger(code, 'code', 0, kMaxInt); if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (this.closed) @@ -2678,7 +2678,7 @@ class ServerHttp2Stream extends Http2Stream { options = undefined; } - validateCallback(callback); + validateFunction(callback, 'callback'); assertIsObject(options, 'options'); options = { ...options }; @@ -3142,7 +3142,7 @@ class Http2SecureServer extends TLSServer { setTimeout(msecs, callback) { this.timeout = msecs; if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); this.on('timeout', callback); } return this; @@ -3169,7 +3169,7 @@ class Http2Server extends NETServer { setTimeout(msecs, callback) { this.timeout = msecs; if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); this.on('timeout', callback); } return this; diff --git a/lib/internal/perf/observe.js b/lib/internal/perf/observe.js index eadc617452e952..a685bac0c0e8b4 100644 --- a/lib/internal/perf/observe.js +++ b/lib/internal/perf/observe.js @@ -46,7 +46,7 @@ const { } = require('internal/errors'); const { - validateCallback, + validateFunction, validateObject, } = require('internal/validators'); @@ -203,7 +203,7 @@ class PerformanceObserver { this[kBuffer] = []; this[kEntryTypes] = new SafeSet(); this[kType] = undefined; - validateCallback(callback); + validateFunction(callback, 'callback'); this[kCallback] = callback; } diff --git a/lib/internal/perf/timerify.js b/lib/internal/perf/timerify.js index dae0b06bf80c8a..cdc0792e582a7e 100644 --- a/lib/internal/perf/timerify.js +++ b/lib/internal/perf/timerify.js @@ -56,7 +56,7 @@ function processComplete(name, start, args, histogram) { } function timerify(fn, options = {}) { - validateFunction(fn, 'fn'); + validateFunction(fn, 'fn', true); validateObject(options, 'options'); const { diff --git a/lib/internal/process/task_queues.js b/lib/internal/process/task_queues.js index 2c53b21040e5d8..77372d1fd7ef32 100644 --- a/lib/internal/process/task_queues.js +++ b/lib/internal/process/task_queues.js @@ -36,7 +36,6 @@ const { const FixedQueue = require('internal/fixed_queue'); const { - validateCallback, validateFunction, } = require('internal/validators'); @@ -102,7 +101,7 @@ function processTicksAndRejections() { // `nextTick()` will not enqueue any callback when the process is about to // exit since the callback would not have a chance to be executed. function nextTick(callback) { - validateCallback(callback); + validateFunction(callback, 'callback'); if (process._exiting) return; diff --git a/lib/internal/readline/callbacks.js b/lib/internal/readline/callbacks.js index ae7cf0c07dda0b..692048c9157199 100644 --- a/lib/internal/readline/callbacks.js +++ b/lib/internal/readline/callbacks.js @@ -12,7 +12,7 @@ const { } = require('internal/errors'); const { - validateCallback, + validateFunction, } = require('internal/validators'); const { CSI, @@ -32,7 +32,7 @@ const { function cursorTo(stream, x, y, callback) { if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (typeof y === 'function') { @@ -60,7 +60,7 @@ function cursorTo(stream, x, y, callback) { function moveCursor(stream, dx, dy, callback) { if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (stream == null || !(dx || dy)) { @@ -94,7 +94,7 @@ function moveCursor(stream, dx, dy, callback) { function clearLine(stream, dir, callback) { if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (stream === null || stream === undefined) { @@ -113,7 +113,7 @@ function clearLine(stream, dir, callback) { function clearScreenDown(stream, callback) { if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); } if (stream === null || stream === undefined) { diff --git a/lib/internal/stream_base_commons.js b/lib/internal/stream_base_commons.js index f126d66d04b297..231ca139d171e2 100644 --- a/lib/internal/stream_base_commons.js +++ b/lib/internal/stream_base_commons.js @@ -27,7 +27,7 @@ const { } = require('internal/timers'); const { isUint8Array } = require('internal/util/types'); const { clearTimeout } = require('timers'); -const { validateCallback } = require('internal/validators'); +const { validateFunction } = require('internal/validators'); const kMaybeDestroy = Symbol('kMaybeDestroy'); const kUpdateTimer = Symbol('kUpdateTimer'); @@ -249,7 +249,7 @@ function setStreamTimeout(msecs, callback) { if (msecs === 0) { if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); this.removeListener('timeout', callback); } } else { @@ -257,7 +257,7 @@ function setStreamTimeout(msecs, callback) { if (this[kSession]) this[kSession][kUpdateTimer](); if (callback !== undefined) { - validateCallback(callback); + validateFunction(callback, 'callback'); this.once('timeout', callback); } } diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index 623973ff316453..7df14057b56d4d 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -25,7 +25,7 @@ const { } = require('internal/errors'); const { - validateCallback, + validateFunction, validateAbortSignal } = require('internal/validators'); @@ -60,7 +60,7 @@ function popCallback(streams) { // Streams should never be an empty array. It should always contain at least // a single stream. Therefore optimize for the average case instead of // checking for length === 0 as well. - validateCallback(streams[streams.length - 1]); + validateFunction(streams[streams.length - 1], 'streams[stream.length - 1]'); return streams.pop(); } diff --git a/lib/internal/timers.js b/lib/internal/timers.js index f48b4057a37ef1..7276f8eb32baed 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -112,7 +112,7 @@ const { ERR_OUT_OF_RANGE } = require('internal/errors').codes; const { - validateCallback, + validateFunction, validateNumber, } = require('internal/validators'); @@ -371,7 +371,7 @@ function insert(item, msecs, start = getLibuvNow()) { function setUnrefTimeout(callback, after) { // Type checking identical to setTimeout() - validateCallback(callback); + validateFunction(callback, 'callback'); const timer = new Timeout(callback, after, undefined, false, false); insert(timer, timer._idleTimeout); diff --git a/lib/internal/url.js b/lib/internal/url.js index 0cca3ecd48cb63..284ffe15fb3eb0 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -73,7 +73,7 @@ const { const path = require('path'); const { - validateCallback, + validateFunction, validateObject, } = require('internal/validators'); @@ -476,7 +476,7 @@ class URLSearchParams { if (!isURLSearchParams(this)) throw new ERR_INVALID_THIS('URLSearchParams'); - validateCallback(callback); + validateFunction(callback, 'callback'); let list = this[searchParams]; diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 9fed5b363db9cb..2bcf876abf5587 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -23,7 +23,6 @@ const { ERR_INVALID_ARG_VALUE, ERR_OUT_OF_RANGE, ERR_UNKNOWN_SIGNAL, - ERR_INVALID_CALLBACK, } } = require('internal/errors'); const { normalizeEncoding } = require('internal/util'); @@ -33,6 +32,8 @@ const { } = require('internal/util/types'); const { signals } = internalBinding('constants').os; +let inspect; + function isInt32(value) { return value === (value | 0); } @@ -219,11 +220,6 @@ function validatePort(port, name = 'Port', allowZero = true) { return port | 0; } -const validateCallback = hideStackFrames((callback) => { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); -}); - const validateAbortSignal = hideStackFrames((signal, name) => { if (signal !== undefined && (signal === null || @@ -233,9 +229,17 @@ const validateAbortSignal = hideStackFrames((signal, name) => { } }); -const validateFunction = hideStackFrames((value, name) => { - if (typeof value !== 'function') - throw new ERR_INVALID_ARG_TYPE(name, 'Function', value); +const validateFunction = hideStackFrames((value, name, allowClass = false) => { + if (typeof value === 'function') { + if (allowClass) return; + + if (inspect === undefined) + ({ inspect } = require('util')); + + if (!inspect(value).startsWith('[class')) return; + } + + throw new ERR_INVALID_ARG_TYPE(name, 'Function', value); }); const validatePlainFunction = hideStackFrames((value, name) => { @@ -268,6 +272,5 @@ module.exports = { validateString, validateUint32, validateUndefined, - validateCallback, validateAbortSignal, }; diff --git a/lib/timers.js b/lib/timers.js index a4543fea1df6bc..cd721ad4550164 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -59,7 +59,7 @@ const { let debug = require('internal/util/debuglog').debuglog('timer', (fn) => { debug = fn; }); -const { validateCallback } = require('internal/validators'); +const { validateFunction } = require('internal/validators'); let timersPromises; @@ -138,7 +138,7 @@ function enroll(item, msecs) { * @returns {Timeout} */ function setTimeout(callback, after, arg1, arg2, arg3) { - validateCallback(callback); + validateFunction(callback, 'callback'); let i, args; switch (arguments.length) { @@ -207,7 +207,7 @@ function clearTimeout(timer) { * @returns {Timeout} */ function setInterval(callback, repeat, arg1, arg2, arg3) { - validateCallback(callback); + validateFunction(callback, 'callback'); let i, args; switch (arguments.length) { @@ -276,7 +276,7 @@ Timeout.prototype[SymbolToPrimitive] = function() { * @returns {Immediate} */ function setImmediate(callback, arg1, arg2, arg3) { - validateCallback(callback); + validateFunction(callback, 'callback'); let i, args; switch (arguments.length) { diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index f92a1091fc9411..e930db92158005 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -1117,7 +1117,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); privateKeyEncoding: { type: 'pkcs1', format: 'pem' } }, cb), { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK' + code: 'ERR_INVALID_ARG_TYPE' }); } } @@ -1518,8 +1518,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); }, { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK', - message: 'Callback must be a function. Received undefined' + code: 'ERR_INVALID_ARG_TYPE', } ); diff --git a/test/parallel/test-crypto-pbkdf2.js b/test/parallel/test-crypto-pbkdf2.js index c9ab6a9c48438e..a62cd97c19318a 100644 --- a/test/parallel/test-crypto-pbkdf2.js +++ b/test/parallel/test-crypto-pbkdf2.js @@ -58,7 +58,7 @@ testPBKDF2('password', 'salt', 32, 32, assert.throws( () => crypto.pbkdf2('password', 'salt', 1, 20, 'sha1'), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' } ); diff --git a/test/parallel/test-crypto-prime.js b/test/parallel/test-crypto-prime.js index 749221b4514ef3..6cd9290877d3c9 100644 --- a/test/parallel/test-crypto-prime.js +++ b/test/parallel/test-crypto-prime.js @@ -37,7 +37,7 @@ const pCheckPrime = promisify(checkPrime); ['hello', false, 123].forEach((i) => { assert.throws(() => generatePrime(80, {}), { - code: 'ERR_INVALID_CALLBACK' + code: 'ERR_INVALID_ARG_TYPE' }); }); diff --git a/test/parallel/test-crypto-random.js b/test/parallel/test-crypto-random.js index bc62d4b6847064..afe2edfc4fb4b3 100644 --- a/test/parallel/test-crypto-random.js +++ b/test/parallel/test-crypto-random.js @@ -30,7 +30,6 @@ const assert = require('assert'); const crypto = require('crypto'); const cryptop = require('crypto').webcrypto; const { kMaxLength } = require('buffer'); -const { inspect } = require('util'); const kMaxInt32 = 2 ** 31 - 1; const kMaxPossibleLength = Math.min(kMaxLength, kMaxInt32); @@ -320,9 +319,8 @@ assert.throws( assert.throws( () => crypto.randomFill(buf, 0, 10, i), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: `Callback must be a function. Received ${inspect(i)}` }); }); @@ -330,9 +328,8 @@ assert.throws( assert.throws( () => crypto.randomBytes(1, i), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: `Callback must be a function. Received ${inspect(i)}` } ); }); @@ -518,9 +515,8 @@ assert.throws( [true, NaN, null, {}, [], 10].forEach((i) => { const cbError = { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: `Callback must be a function. Received ${inspect(i)}` }; assert.throws(() => crypto.randomInt(0, 1, i), cbError); }); diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js index 7b695a36f2b5a4..5f860c75bbebf0 100644 --- a/test/parallel/test-crypto-scrypt.js +++ b/test/parallel/test-crypto-scrypt.js @@ -211,7 +211,7 @@ for (const { args, expected } of badargs) { } { - const expected = { code: 'ERR_INVALID_CALLBACK' }; + const expected = { code: 'ERR_INVALID_ARG_TYPE' }; assert.throws(() => crypto.scrypt('', '', 42, null), expected); assert.throws(() => crypto.scrypt('', '', 42, {}, null), expected); assert.throws(() => crypto.scrypt('', '', 42, {}), expected); diff --git a/test/parallel/test-crypto-secret-keygen.js b/test/parallel/test-crypto-secret-keygen.js index ab662aeb5d123b..0739393643d6bb 100644 --- a/test/parallel/test-crypto-secret-keygen.js +++ b/test/parallel/test-crypto-secret-keygen.js @@ -44,7 +44,7 @@ const { }); assert.throws(() => generateKey('aes', { length: 256 }), { - code: 'ERR_INVALID_CALLBACK' + code: 'ERR_INVALID_ARG_TYPE' }); assert.throws(() => generateKey('hmac', { length: -1 }, common.mustNotCall()), { diff --git a/test/parallel/test-dns-lookup.js b/test/parallel/test-dns-lookup.js index aa4a1b8abef6df..461e705a5e3cb6 100644 --- a/test/parallel/test-dns-lookup.js +++ b/test/parallel/test-dns-lookup.js @@ -39,14 +39,14 @@ common.expectWarning({ assert.throws(() => { dns.lookup(false, 'cb'); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); assert.throws(() => { dns.lookup(false, 'options', 'cb'); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); diff --git a/test/parallel/test-dns-resolvens-typeerror.js b/test/parallel/test-dns-resolvens-typeerror.js index 54e0da57604ed8..2beb33c869e6da 100644 --- a/test/parallel/test-dns-resolvens-typeerror.js +++ b/test/parallel/test-dns-resolvens-typeerror.js @@ -49,7 +49,7 @@ assert.throws( assert.throws( () => dns.resolveNs(''), // bad callback { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' } ); diff --git a/test/parallel/test-dns.js b/test/parallel/test-dns.js index 6f3790d427d353..18218308486f4e 100644 --- a/test/parallel/test-dns.js +++ b/test/parallel/test-dns.js @@ -230,12 +230,12 @@ assert.deepStrictEqual(dns.getServers(), []); } assert.throws(() => dns.lookup('nodejs.org'), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); assert.throws(() => dns.lookup('nodejs.org', 4), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); @@ -331,7 +331,7 @@ portErr('test'); assert.throws(() => { dns.lookupService('0.0.0.0', 80, null); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); diff --git a/test/parallel/test-fs-access.js b/test/parallel/test-fs-access.js index d8e1c94300d2ed..633a3d7ace4b7d 100644 --- a/test/parallel/test-fs-access.js +++ b/test/parallel/test-fs-access.js @@ -138,7 +138,7 @@ assert.throws( fs.access(__filename, fs.F_OK); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); @@ -147,7 +147,7 @@ assert.throws( fs.access(__filename, fs.F_OK, {}); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); diff --git a/test/parallel/test-fs-append-file.js b/test/parallel/test-fs-append-file.js index 70919830f6cb0b..20ad2c01758798 100644 --- a/test/parallel/test-fs-append-file.js +++ b/test/parallel/test-fs-append-file.js @@ -191,4 +191,4 @@ const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; assert.throws( () => fs.appendFile(join(tmpdir.path, 'append6.txt'), console.log), - { code: 'ERR_INVALID_CALLBACK' }); + { code: 'ERR_INVALID_ARG_TYPE' }); diff --git a/test/parallel/test-fs-close-errors.js b/test/parallel/test-fs-close-errors.js index 52930a203eddbb..112b93739e784c 100644 --- a/test/parallel/test-fs-close-errors.js +++ b/test/parallel/test-fs-close-errors.js @@ -23,7 +23,7 @@ const fs = require('fs'); const fd = fs.openSync(__filename, 'r'); const errObj = { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }; diff --git a/test/parallel/test-fs-copyfile.js b/test/parallel/test-fs-copyfile.js index 51250d7b83145c..1bfa410a124d2d 100644 --- a/test/parallel/test-fs-copyfile.js +++ b/test/parallel/test-fs-copyfile.js @@ -103,7 +103,7 @@ fs.copyFile(src, dest, common.mustSucceed(() => { assert.throws(() => { fs.copyFile(src, dest, 0, 0); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); diff --git a/test/parallel/test-fs-exists.js b/test/parallel/test-fs-exists.js index 75b7adfc3ee3d0..857f3f26174549 100644 --- a/test/parallel/test-fs-exists.js +++ b/test/parallel/test-fs-exists.js @@ -25,9 +25,9 @@ const assert = require('assert'); const fs = require('fs'); const f = __filename; -assert.throws(() => fs.exists(f), { code: 'ERR_INVALID_CALLBACK' }); -assert.throws(() => fs.exists(), { code: 'ERR_INVALID_CALLBACK' }); -assert.throws(() => fs.exists(f, {}), { code: 'ERR_INVALID_CALLBACK' }); +assert.throws(() => fs.exists(f), { code: 'ERR_INVALID_ARG_TYPE' }); +assert.throws(() => fs.exists(), { code: 'ERR_INVALID_ARG_TYPE' }); +assert.throws(() => fs.exists(f, {}), { code: 'ERR_INVALID_ARG_TYPE' }); fs.exists(f, common.mustCall(function(y) { assert.strictEqual(y, true); diff --git a/test/parallel/test-fs-lchmod.js b/test/parallel/test-fs-lchmod.js index d0cba919b64754..ae5cb3ba2a230a 100644 --- a/test/parallel/test-fs-lchmod.js +++ b/test/parallel/test-fs-lchmod.js @@ -14,9 +14,9 @@ if (!common.isOSX) { } // Check callback -assert.throws(() => fs.lchmod(f), { code: 'ERR_INVALID_CALLBACK' }); -assert.throws(() => fs.lchmod(), { code: 'ERR_INVALID_CALLBACK' }); -assert.throws(() => fs.lchmod(f, {}), { code: 'ERR_INVALID_CALLBACK' }); +assert.throws(() => fs.lchmod(f), { code: 'ERR_INVALID_ARG_TYPE' }); +assert.throws(() => fs.lchmod(), { code: 'ERR_INVALID_ARG_TYPE' }); +assert.throws(() => fs.lchmod(f, {}), { code: 'ERR_INVALID_ARG_TYPE' }); // Check path [false, 1, {}, [], null, undefined].forEach((i) => { diff --git a/test/parallel/test-fs-lchown.js b/test/parallel/test-fs-lchown.js index ba2b4b85fb9c90..899f9c630188d6 100644 --- a/test/parallel/test-fs-lchown.js +++ b/test/parallel/test-fs-lchown.js @@ -46,7 +46,7 @@ const { promises } = fs; [false, 1, 'test', {}, [], null, undefined].forEach((i) => { assert.throws(() => fs.lchown('not_a_file_that_exists', 1, 1, i), { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK' + code: 'ERR_INVALID_ARG_TYPE' }); }); diff --git a/test/parallel/test-fs-make-callback.js b/test/parallel/test-fs-make-callback.js index 0cbc4a7fe3e186..d9341ab06f90cc 100644 --- a/test/parallel/test-fs-make-callback.js +++ b/test/parallel/test-fs-make-callback.js @@ -19,7 +19,7 @@ function testMakeCallback(cb) { function invalidCallbackThrowsTests() { callbackThrowValues.forEach((value) => { assert.throws(testMakeCallback(value), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); }); diff --git a/test/parallel/test-fs-makeStatsCallback.js b/test/parallel/test-fs-makeStatsCallback.js index 52d129db2b6bc8..953fc065e84853 100644 --- a/test/parallel/test-fs-makeStatsCallback.js +++ b/test/parallel/test-fs-makeStatsCallback.js @@ -17,7 +17,7 @@ testMakeStatsCallback(common.mustCall())(); function invalidCallbackThrowsTests() { callbackThrowValues.forEach((value) => { assert.throws(testMakeStatsCallback(value), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); }); diff --git a/test/parallel/test-fs-open.js b/test/parallel/test-fs-open.js index 92dd8f5f48718b..29580019db6f61 100644 --- a/test/parallel/test-fs-open.js +++ b/test/parallel/test-fs-open.js @@ -67,7 +67,7 @@ for (const extra of [[], ['r'], ['r', 0], ['r', 0, 'bad callback']]) { assert.throws( () => fs.open(__filename, ...extra), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' } ); diff --git a/test/parallel/test-fs-opendir.js b/test/parallel/test-fs-opendir.js index 4c4681ef48e2ff..1a4aded61dcd1a 100644 --- a/test/parallel/test-fs-opendir.js +++ b/test/parallel/test-fs-opendir.js @@ -38,7 +38,7 @@ const dirconcurrentError = { }; const invalidCallbackObj = { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }; @@ -94,7 +94,7 @@ assert.throws(function() { assert.throws(function() { fs.opendir(__filename); -}, /TypeError \[ERR_INVALID_CALLBACK\]: Callback must be a function/); +}, /TypeError \[ERR_INVALID_ARG_TYPE\]: The "callback" argument must be of type function/); fs.opendir(__filename, common.mustCall(function(e) { assert.strictEqual(e.code, 'ENOTDIR'); @@ -247,7 +247,7 @@ doConcurrentAsyncAndSyncOps().then(common.mustCall()); // Check read throw exceptions on invalid callback { const dir = fs.opendirSync(testDir); - assert.throws(() => dir.read('INVALID_CALLBACK'), /ERR_INVALID_CALLBACK/); + assert.throws(() => dir.read('INVALID_CALLBACK'), /ERR_INVALID_ARG_TYPE/); } // Check that concurrent read() operations don't do weird things. diff --git a/test/parallel/test-fs-read.js b/test/parallel/test-fs-read.js index 70296172ed9988..2b3dab4f243b90 100644 --- a/test/parallel/test-fs-read.js +++ b/test/parallel/test-fs-read.js @@ -73,8 +73,7 @@ assert.throws(() => new fs.Dir(), { assert.throws( () => fs.read(fd, Buffer.alloc(1), 0, 1, 0), { - message: 'Callback must be a function. Received undefined', - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', } ); diff --git a/test/parallel/test-http2-client-rststream-before-connect.js b/test/parallel/test-http2-client-rststream-before-connect.js index 2acdefdfbe28f8..bc0cb5ff619dc0 100644 --- a/test/parallel/test-http2-client-rststream-before-connect.js +++ b/test/parallel/test-http2-client-rststream-before-connect.js @@ -5,7 +5,6 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const h2 = require('http2'); -const { inspect } = require('util'); const server = h2.createServer(); server.on('stream', (stream) => { @@ -35,8 +34,7 @@ server.listen(0, common.mustCall(() => { () => req.close(closeCode, notFunction), { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK', - message: `Callback must be a function. Received ${inspect(notFunction)}` + code: 'ERR_INVALID_ARG_TYPE', } ); assert.strictEqual(req.closed, false); diff --git a/test/parallel/test-http2-client-settings-before-connect.js b/test/parallel/test-http2-client-settings-before-connect.js index 406ddd86ab5e9b..d370b49ce050dd 100644 --- a/test/parallel/test-http2-client-settings-before-connect.js +++ b/test/parallel/test-http2-client-settings-before-connect.js @@ -5,7 +5,6 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); const h2 = require('http2'); -const { inspect } = require('util'); const server = h2.createServer(); @@ -54,9 +53,7 @@ server.listen(0, common.mustCall(() => { () => client.settings({}, invalidCallback), { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK', - message: - `Callback must be a function. Received ${inspect(invalidCallback)}` + code: 'ERR_INVALID_ARG_TYPE', } ) ); diff --git a/test/parallel/test-http2-compat-serverresponse-createpushresponse.js b/test/parallel/test-http2-compat-serverresponse-createpushresponse.js index f25eab444f2dfd..0546bde1e2ca18 100644 --- a/test/parallel/test-http2-compat-serverresponse-createpushresponse.js +++ b/test/parallel/test-http2-compat-serverresponse-createpushresponse.js @@ -22,9 +22,8 @@ const server = h2.createServer((request, response) => { ':method': 'GET' }, undefined), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: 'Callback must be a function. Received undefined' } ); diff --git a/test/parallel/test-http2-ping.js b/test/parallel/test-http2-ping.js index d775e93333797e..9a6b30194d0c30 100644 --- a/test/parallel/test-http2-ping.js +++ b/test/parallel/test-http2-ping.js @@ -7,7 +7,6 @@ if (!common.hasCrypto) const async_hooks = require('async_hooks'); const assert = require('assert'); const http2 = require('http2'); -const { inspect } = require('util'); const pings = new Set(); const events = [0, 0, 0, 0]; @@ -120,9 +119,7 @@ server.listen(0, common.mustCall(() => { () => client.ping(payload, invalidCallback), { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK', - message: 'Callback must be a function. ' + - `Received ${inspect(invalidCallback)}` + code: 'ERR_INVALID_ARG_TYPE', } ) ); diff --git a/test/parallel/test-http2-server-push-stream-errors-args.js b/test/parallel/test-http2-server-push-stream-errors-args.js index ba0aabcf5cf658..944532ec513958 100644 --- a/test/parallel/test-http2-server-push-stream-errors-args.js +++ b/test/parallel/test-http2-server-push-stream-errors-args.js @@ -21,8 +21,7 @@ server.on('stream', common.mustCall((stream, headers) => { ':authority': `localhost:${port}`, }, {}, 'callback'), { - code: 'ERR_INVALID_CALLBACK', - message: "Callback must be a function. Received 'callback'" + code: 'ERR_INVALID_ARG_TYPE', } ); diff --git a/test/parallel/test-http2-server-settimeout-no-callback.js b/test/parallel/test-http2-server-settimeout-no-callback.js index 31a64731f6dabc..79094b57772aba 100644 --- a/test/parallel/test-http2-server-settimeout-no-callback.js +++ b/test/parallel/test-http2-server-settimeout-no-callback.js @@ -6,7 +6,6 @@ if (!common.hasCrypto) const assert = require('assert'); const http2 = require('http2'); -const { inspect } = require('util'); // Verify that setTimeout callback verifications work correctly const verifyCallbacks = (server) => { @@ -17,9 +16,7 @@ const verifyCallbacks = (server) => { () => server.setTimeout(testTimeout, notFunction), { name: 'TypeError', - code: 'ERR_INVALID_CALLBACK', - message: 'Callback must be a function. ' + - `Received ${inspect(notFunction)}` + code: 'ERR_INVALID_ARG_TYPE', } ); }); diff --git a/test/parallel/test-http2-timeouts.js b/test/parallel/test-http2-timeouts.js index a67b7227154080..bf84289eef27da 100644 --- a/test/parallel/test-http2-timeouts.js +++ b/test/parallel/test-http2-timeouts.js @@ -29,17 +29,15 @@ server.on('stream', common.mustCall((stream) => { assert.throws( () => stream.setTimeout(0, Symbol('test')), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: 'Callback must be a function. Received Symbol(test)' } ); assert.throws( () => stream.setTimeout(100, {}), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: 'Callback must be a function. Received {}' } ); })); diff --git a/test/parallel/test-inspector-module.js b/test/parallel/test-inspector-module.js index 5f5efe4cb80061..cdbbc69229dd55 100644 --- a/test/parallel/test-inspector-module.js +++ b/test/parallel/test-inspector-module.js @@ -6,7 +6,6 @@ common.skipIfInspectorDisabled(); const assert = require('assert'); const { Session } = require('inspector'); -const { inspect } = require('util'); const session = new Session(); @@ -52,9 +51,8 @@ session.post('Runtime.evaluate', { expression: '2 + 2' }); assert.throws( () => session.post('test', {}, i), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: `Callback must be a function. Received ${inspect(i)}` } ); }); diff --git a/test/parallel/test-net-socket-timeout.js b/test/parallel/test-net-socket-timeout.js index 209359fda60810..58906a25df42b9 100644 --- a/test/parallel/test-net-socket-timeout.js +++ b/test/parallel/test-net-socket-timeout.js @@ -23,7 +23,6 @@ const common = require('../common'); const net = require('net'); const assert = require('assert'); -const { inspect } = require('util'); // Verify that invalid delays throw const s = new net.Socket(); @@ -58,10 +57,8 @@ for (let i = 0; i < invalidCallbacks.length; i++) { assert.throws( () => s.setTimeout(mesc, invalidCallbacks[i]), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: 'Callback must be a function. ' + - `Received ${inspect(invalidCallbacks[i])}` } ) ); diff --git a/test/parallel/test-next-tick-errors.js b/test/parallel/test-next-tick-errors.js index 56480adcf53c27..6fd079625afae2 100644 --- a/test/parallel/test-next-tick-errors.js +++ b/test/parallel/test-next-tick-errors.js @@ -45,7 +45,7 @@ function testNextTickWith(val) { assert.throws(() => { process.nextTick(val); }, { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); } diff --git a/test/parallel/test-performanceobserver.js b/test/parallel/test-performanceobserver.js index 4862f5fbf02f25..6d83f5718d0498 100644 --- a/test/parallel/test-performanceobserver.js +++ b/test/parallel/test-performanceobserver.js @@ -3,7 +3,6 @@ const common = require('../common'); const assert = require('assert'); -const { inspect } = require('util'); const { internalBinding } = require('internal/test/binding'); const { observerCounts: counts @@ -27,9 +26,8 @@ assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_HTTP2], 0); assert.throws( () => new PerformanceObserver(i), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: `Callback must be a function. Received ${inspect(i)}` } ); }); diff --git a/test/parallel/test-process-next-tick.js b/test/parallel/test-process-next-tick.js index 691bf57b3751c5..66913beebf2f7b 100644 --- a/test/parallel/test-process-next-tick.js +++ b/test/parallel/test-process-next-tick.js @@ -22,7 +22,6 @@ 'use strict'; const common = require('../common'); const assert = require('assert'); -const { inspect } = require('util'); const N = 2; function cb() { @@ -43,9 +42,8 @@ process.on('exit', function() { assert.throws( () => process.nextTick(i), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: `Callback must be a function. Received ${inspect(i)}` } ); }); diff --git a/test/parallel/test-readline-csi.js b/test/parallel/test-readline-csi.js index 13dbbfa30f6fa2..75cd942f3b69f7 100644 --- a/test/parallel/test-readline-csi.js +++ b/test/parallel/test-readline-csi.js @@ -36,7 +36,7 @@ assert.strictEqual(readline.clearScreenDown(writable, common.mustCall()), true); // Verify that clearScreenDown() throws on invalid callback. assert.throws(() => { readline.clearScreenDown(writable, null); -}, /ERR_INVALID_CALLBACK/); +}, /ERR_INVALID_ARG_TYPE/); // Verify that clearScreenDown() does not throw on null or undefined stream. assert.strictEqual(readline.clearScreenDown(null, common.mustCall((err) => { @@ -64,7 +64,7 @@ assert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning); // Verify that clearLine() throws on invalid callback. assert.throws(() => { readline.clearLine(writable, 0, null); -}, /ERR_INVALID_CALLBACK/); +}, /ERR_INVALID_ARG_TYPE/); // Verify that clearLine() does not throw on null or undefined stream. assert.strictEqual(readline.clearLine(null, 0), true); @@ -100,7 +100,7 @@ assert.strictEqual(readline.clearLine(undefined, 0, common.mustCall()), true); // Verify that moveCursor() throws on invalid callback. assert.throws(() => { readline.moveCursor(writable, 1, 1, null); -}, /ERR_INVALID_CALLBACK/); +}, /ERR_INVALID_ARG_TYPE/); // Verify that moveCursor() does not throw on null or undefined stream. assert.strictEqual(readline.moveCursor(null, 1, 1), true); @@ -160,7 +160,7 @@ assert.strictEqual(writable.data, '\x1b[2G'); // Verify that cursorTo() throws on invalid callback. assert.throws(() => { readline.cursorTo(writable, 1, 1, null); -}, /ERR_INVALID_CALLBACK/); +}, /ERR_INVALID_ARG_TYPE/); // Verify that cursorTo() throws if x or y is NaN. assert.throws(() => { diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js index 192f971b29daca..e97b48d753ae81 100644 --- a/test/parallel/test-stream-pipeline.js +++ b/test/parallel/test-stream-pipeline.js @@ -66,7 +66,7 @@ const tsp = require('timers/promises'); }, /ERR_MISSING_ARGS/); assert.throws(() => { pipeline(); - }, /ERR_INVALID_CALLBACK/); + }, /ERR_INVALID_ARG_TYPE/); } { @@ -560,7 +560,7 @@ const tsp = require('timers/promises'); assert.throws( () => pipeline(read, transform, write), - { code: 'ERR_INVALID_CALLBACK' } + { code: 'ERR_INVALID_ARG_TYPE' } ); } diff --git a/test/parallel/test-timers-refresh.js b/test/parallel/test-timers-refresh.js index 17b3b34af5662b..a26c4efac30b6c 100644 --- a/test/parallel/test-timers-refresh.js +++ b/test/parallel/test-timers-refresh.js @@ -6,7 +6,6 @@ const common = require('../common'); const { strictEqual, throws } = require('assert'); const { setUnrefTimeout } = require('internal/timers'); -const { inspect } = require('util'); // Schedule the unrefed cases first so that the later case keeps the event loop // active. @@ -37,8 +36,7 @@ const { inspect } = require('util'); throws( () => setUnrefTimeout(cb), { - code: 'ERR_INVALID_CALLBACK', - message: `Callback must be a function. Received ${inspect(cb)}` + code: 'ERR_INVALID_ARG_TYPE', } ); }); diff --git a/test/parallel/test-timers-throw-when-cb-not-function.js b/test/parallel/test-timers-throw-when-cb-not-function.js index 75f49b0f3b967e..f7432af233c8c2 100644 --- a/test/parallel/test-timers-throw-when-cb-not-function.js +++ b/test/parallel/test-timers-throw-when-cb-not-function.js @@ -9,7 +9,7 @@ function doSetTimeout(callback, after) { } const errMessage = { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }; diff --git a/test/parallel/test-tls-disable-renegotiation.js b/test/parallel/test-tls-disable-renegotiation.js index f720eec6c6448a..3de7c79cf04025 100644 --- a/test/parallel/test-tls-disable-renegotiation.js +++ b/test/parallel/test-tls-disable-renegotiation.js @@ -61,12 +61,12 @@ server.listen(0, common.mustCall(() => { }); assert.throws(() => client.renegotiate({}, false), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', }); assert.throws(() => client.renegotiate({}, null), { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', }); diff --git a/test/parallel/test-whatwg-url-custom-searchparams.js b/test/parallel/test-whatwg-url-custom-searchparams.js index 272435b001a366..0b2087ac246313 100644 --- a/test/parallel/test-whatwg-url-custom-searchparams.js +++ b/test/parallel/test-whatwg-url-custom-searchparams.js @@ -74,7 +74,7 @@ sp.forEach(function() { { const callbackErr = { - code: 'ERR_INVALID_CALLBACK', + code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }; assert.throws(() => sp.forEach(), callbackErr); From a67487472d68ccc793bdd9aeba1d5cf408f2cf36 Mon Sep 17 00:00:00 2001 From: Mohammed Keyvanzadeh Date: Fri, 4 Feb 2022 02:59:44 +0330 Subject: [PATCH 2/2] fixup! lib: replace validator and error Reverted the changes to the `validateFunction()` validator, added `code` after `error`, removed the link re-directing to `ERR_INAVLID_ARG_TYPE` error code, and reverted the changes to the `ERR_INVALID_ARG_TYPE` error code. --- doc/api/deprecations.md | 5 +---- lib/internal/errors.js | 5 +---- lib/internal/perf/timerify.js | 2 +- lib/internal/validators.js | 16 +++------------- 4 files changed, 6 insertions(+), 22 deletions(-) diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 974dd5443352e6..1272c652b46085 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -3067,11 +3067,9 @@ changes: Type: End-of-Life -This error was removed due to adding more confusion to +This error code was removed due to adding more confusion to the errors used for value type validation. -Use [`ERR_INVALID_ARG_TYPE`][] instead. - [Legacy URL API]: url.md#legacy-url-api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 @@ -3086,7 +3084,6 @@ Use [`ERR_INVALID_ARG_TYPE`][] instead. [`Buffer.isBuffer()`]: buffer.md#static-method-bufferisbufferobj [`Cipher`]: crypto.md#class-cipher [`Decipher`]: crypto.md#class-decipher -[`ERR_INVALID_ARG_TYPE`]: errors.md#err_invalid_arg_type [`REPLServer.clearBufferedCommand()`]: repl.md#replserverclearbufferedcommand [`ReadStream.open()`]: fs.md#class-fsreadstream [`Server.getConnections()`]: net.md#servergetconnectionscallback diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 3b5d0d8e432cf9..a4e32c12cecae1 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1208,10 +1208,7 @@ E('ERR_INVALID_ARG_TYPE', if (actual == null) { msg += `. Received ${actual}`; } else if (typeof actual === 'function' && actual.name) { - const inspected = lazyInternalUtilInspect() - .inspect(actual); - msg += `. Received ${inspected.startsWith('[class') ? - 'class' : 'function'} ${actual.name}`; + msg += `. Received function ${actual.name}`; } else if (typeof actual === 'object') { if (actual.constructor && actual.constructor.name) { msg += `. Received an instance of ${actual.constructor.name}`; diff --git a/lib/internal/perf/timerify.js b/lib/internal/perf/timerify.js index cdc0792e582a7e..dae0b06bf80c8a 100644 --- a/lib/internal/perf/timerify.js +++ b/lib/internal/perf/timerify.js @@ -56,7 +56,7 @@ function processComplete(name, start, args, histogram) { } function timerify(fn, options = {}) { - validateFunction(fn, 'fn', true); + validateFunction(fn, 'fn'); validateObject(options, 'options'); const { diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 2bcf876abf5587..b07eebfbd8b1a0 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -32,8 +32,6 @@ const { } = require('internal/util/types'); const { signals } = internalBinding('constants').os; -let inspect; - function isInt32(value) { return value === (value | 0); } @@ -229,17 +227,9 @@ const validateAbortSignal = hideStackFrames((signal, name) => { } }); -const validateFunction = hideStackFrames((value, name, allowClass = false) => { - if (typeof value === 'function') { - if (allowClass) return; - - if (inspect === undefined) - ({ inspect } = require('util')); - - if (!inspect(value).startsWith('[class')) return; - } - - throw new ERR_INVALID_ARG_TYPE(name, 'Function', value); +const validateFunction = hideStackFrames((value, name) => { + if (typeof value !== 'function') + throw new ERR_INVALID_ARG_TYPE(name, 'Function', value); }); const validatePlainFunction = hideStackFrames((value, name) => {