From 7fe1b5ef5a54df9a7435c9e027cc3da1c47e2557 Mon Sep 17 00:00:00 2001 From: ZiJian Liu Date: Wed, 23 Dec 2020 19:22:00 +0800 Subject: [PATCH] lib: refactor to use validateCallback PR-URL: https://github.com/nodejs/node/pull/36609 Reviewed-By: Rich Trott Reviewed-By: Antoine du Hamel --- lib/_tls_wrap.js | 7 +++--- lib/dns.js | 35 ++++++++++++++-------------- lib/fs.js | 19 ++++++--------- lib/inspector.js | 10 ++++---- lib/internal/crypto/diffiehellman.js | 8 +++---- lib/internal/crypto/hkdf.js | 5 ++-- lib/internal/crypto/keygen.js | 8 +++---- lib/internal/crypto/pbkdf2.js | 5 ++-- lib/internal/crypto/random.js | 19 ++++++++------- lib/internal/crypto/scrypt.js | 5 ++-- lib/internal/fs/dir.js | 15 +++++------- lib/internal/http2/compat.js | 9 +++---- lib/internal/http2/core.js | 26 ++++++++++----------- lib/internal/process/task_queues.js | 6 ++--- lib/internal/stream_base_commons.js | 10 +++----- lib/internal/streams/pipeline.js | 6 ++--- lib/internal/timers.js | 10 ++++---- lib/internal/url.js | 7 +++--- lib/perf_hooks.js | 7 +++--- lib/readline.js | 22 ++++++++++------- 20 files changed, 114 insertions(+), 125 deletions(-) diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index adbefa4839826d..1447253bf73224 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -67,7 +67,6 @@ const { connResetException, codes } = require('internal/errors'); const { ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_MULTIPLE_CALLBACK, ERR_SOCKET_CLOSED, ERR_TLS_DH_PARAM_SIZE, @@ -85,6 +84,7 @@ const { getAllowUnauthorized, } = require('internal/options'); const { + validateCallback, validateString, validateBuffer, validateUint32 @@ -825,8 +825,9 @@ TLSSocket.prototype._init = function(socket, wrap) { TLSSocket.prototype.renegotiate = function(options, callback) { if (options === null || typeof options !== 'object') throw new ERR_INVALID_ARG_TYPE('options', 'Object', options); - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } debug('%s renegotiate()', this._tlsOptions.isServer ? 'server' : 'client', diff --git a/lib/dns.js b/lib/dns.js index 0c1b259d7341ee..1116c73f670438 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -45,10 +45,10 @@ const { const { ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_MISSING_ARGS, } = errors.codes; const { + validateCallback, validatePort, validateString, validateOneOf, @@ -101,20 +101,24 @@ function lookup(hostname, options, callback) { // Parse arguments if (hostname && typeof hostname !== 'string') { throw new ERR_INVALID_ARG_TYPE('hostname', 'string', hostname); - } else if (typeof options === 'function') { + } + + if (typeof options === 'function') { callback = options; family = 0; - } else if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } else if (options !== null && typeof options === 'object') { - hints = options.hints >>> 0; - family = options.family >>> 0; - all = options.all === true; - verbatim = options.verbatim === true; - - validateHints(hints); } else { - family = options >>> 0; + validateCallback(callback); + + if (options !== null && typeof options === 'object') { + hints = options.hints >>> 0; + family = options.family >>> 0; + all = options.all === true; + verbatim = options.verbatim === true; + + validateHints(hints); + } else { + family = options >>> 0; + } } validateOneOf(family, 'family', [0, 4, 6]); @@ -177,8 +181,7 @@ function lookupService(address, port, callback) { validatePort(port); - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); port = +port; @@ -217,9 +220,7 @@ function resolver(bindingName) { } validateString(name, 'name'); - if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } + validateCallback(callback); const req = new QueryReqWrap(); req.bindingName = bindingName; diff --git a/lib/fs.js b/lib/fs.js index 93e875311e08a6..918762877e6f99 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -75,7 +75,6 @@ const { ERR_FS_FILE_TOO_LARGE, ERR_INVALID_ARG_VALUE, ERR_INVALID_ARG_TYPE, - ERR_INVALID_CALLBACK, ERR_FEATURE_UNAVAILABLE_ON_PLATFORM }, hideStackFrames, @@ -125,6 +124,7 @@ const { isUint32, parseFileMode, validateBuffer, + validateCallback, validateInteger, validateInt32 } = require('internal/validators'); @@ -170,19 +170,16 @@ function showTruncateDeprecation() { } function maybeCallback(cb) { - if (typeof cb === 'function') - return cb; + validateCallback(cb); - throw new ERR_INVALID_CALLBACK(cb); + return cb; } // Ensure that callbacks run in the global context. Only use this function // for callbacks that are passed to the binding layer, callbacks that are // invoked from JS already run in the proper scope. function makeCallback(cb) { - if (typeof cb !== 'function') { - throw new ERR_INVALID_CALLBACK(cb); - } + validateCallback(cb); return (...args) => cb(...args); } @@ -191,9 +188,7 @@ function makeCallback(cb) { // an optimization, since the data passed back to the callback needs to be // transformed anyway. function makeStatsCallback(cb) { - if (typeof cb !== 'function') { - throw new ERR_INVALID_CALLBACK(cb); - } + validateCallback(cb); return (err, stats) => { if (err) return cb(err); @@ -2014,8 +2009,8 @@ function copyFile(src, dest, mode, callback) { if (typeof mode === 'function') { callback = mode; mode = 0; - } else if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); + } else { + validateCallback(callback); } src = getValidatedPath(src, 'src'); diff --git a/lib/inspector.js b/lib/inspector.js index 007822ffa20f0d..30b2e6407ce659 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -17,7 +17,6 @@ const { ERR_INSPECTOR_NOT_ACTIVE, ERR_INSPECTOR_NOT_WORKER, ERR_INVALID_ARG_TYPE, - ERR_INVALID_CALLBACK } = require('internal/errors').codes; const { hasInspector } = internalBinding('config'); @@ -26,7 +25,10 @@ if (!hasInspector) const EventEmitter = require('events'); const { queueMicrotask } = require('internal/process/task_queues'); -const { validateString } = require('internal/validators'); +const { + validateCallback, + validateString, +} = require('internal/validators'); const { isMainThread } = require('worker_threads'); const { @@ -100,8 +102,8 @@ class Session extends EventEmitter { if (params && typeof params !== 'object') { throw new ERR_INVALID_ARG_TYPE('params', 'Object', params); } - if (callback && typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); + if (callback) { + validateCallback(callback); } if (!this[connectionSymbol]) { diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index 2a8795e378f3e0..a28d61369b1c94 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -31,11 +31,11 @@ const { ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, } } = require('internal/errors'); const { + validateCallback, validateInt32, validateObject, validateString, @@ -325,8 +325,7 @@ function deriveBitsECDH(name, publicKey, privateKey, callback) { validateString(name, 'name'); validateObject(publicKey, 'publicKey'); validateObject(privateKey, 'privateKey'); - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); const job = new ECDHBitsJob(kCryptoJobAsync, name, publicKey, privateKey); job.ondone = (error, bits) => { if (error) return FunctionPrototypeCall(callback, job, error); @@ -340,8 +339,7 @@ function deriveBitsECDH(name, publicKey, privateKey, callback) { function deriveBitsDH(publicKey, privateKey, callback) { validateObject(publicKey, 'publicKey'); validateObject(privateKey, 'privateKey'); - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(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 1b013e5ff1591c..7949fa33d2e077 100644 --- a/lib/internal/crypto/hkdf.js +++ b/lib/internal/crypto/hkdf.js @@ -13,6 +13,7 @@ const { } = internalBinding('crypto'); const { + validateCallback, validateInteger, validateString, validateUint32, @@ -41,7 +42,6 @@ const { const { codes: { - ERR_INVALID_CALLBACK, ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE, ERR_MISSING_OPTION, @@ -112,8 +112,7 @@ function hkdf(hash, key, salt, info, length, callback) { length, } = validateParameters(hash, key, salt, info, length)); - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(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 5f29a3153b94e0..2b0d58afd663fc 100644 --- a/lib/internal/crypto/keygen.js +++ b/lib/internal/crypto/keygen.js @@ -40,6 +40,7 @@ const { customPromisifyArgs } = require('internal/util'); const { isUint32, + validateCallback, validateString, validateInteger, validateObject, @@ -50,7 +51,6 @@ const { codes: { ERR_INCOMPATIBLE_OPTION_PAIR, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_MISSING_OPTION, } } = require('internal/errors'); @@ -68,8 +68,7 @@ function generateKeyPair(type, options, callback) { callback = options; options = undefined; } - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); const job = createJob(kCryptoJobAsync, type, options); @@ -353,8 +352,7 @@ function generateKey(type, options, callback) { options = undefined; } - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); const job = generateKeyJob(kCryptoJobAsync, type, options); diff --git a/lib/internal/crypto/pbkdf2.js b/lib/internal/crypto/pbkdf2.js index 868e0f7fbb214e..98f4efb4f333bf 100644 --- a/lib/internal/crypto/pbkdf2.js +++ b/lib/internal/crypto/pbkdf2.js @@ -14,13 +14,13 @@ const { } = internalBinding('crypto'); const { + validateCallback, validateInteger, validateUint32, } = require('internal/validators'); const { ERR_INVALID_ARG_TYPE, - ERR_INVALID_CALLBACK, ERR_MISSING_OPTION, } = require('internal/errors').codes; @@ -41,8 +41,7 @@ function pbkdf2(password, salt, iterations, keylen, digest, callback) { ({ password, salt, iterations, keylen, digest } = check(password, salt, iterations, keylen, digest)); - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); const job = new PBKDF2Job( kCryptoJobAsync, diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index dca43647a6635a..93b32b92007908 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -23,12 +23,14 @@ const { kMaxLength } = require('buffer'); const { codes: { ERR_INVALID_ARG_TYPE, - ERR_INVALID_CALLBACK, ERR_OUT_OF_RANGE, } } = require('internal/errors'); -const { validateNumber } = require('internal/validators'); +const { + validateNumber, + validateCallback, +} = require('internal/validators'); const { isArrayBufferView, @@ -73,8 +75,9 @@ function assertSize(size, elementSize, offset, length) { function randomBytes(size, callback) { size = assertSize(size, 1, 0, Infinity); - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } const buf = new FastBuffer(size); @@ -141,8 +144,8 @@ function randomFill(buf, offset, size, callback) { } else if (typeof size === 'function') { callback = size; size = buf.byteLength - offset; - } else if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); + } else { + validateCallback(callback); } offset = assertOffset(offset, elementSize, buf.byteLength); @@ -188,8 +191,8 @@ function randomInt(min, max, callback) { } const isSync = typeof callback === 'undefined'; - if (!isSync && typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); + if (!isSync) { + validateCallback(callback); } if (!NumberIsSafeInteger(min)) { throw new ERR_INVALID_ARG_TYPE('min', 'a safe integer', min); diff --git a/lib/internal/crypto/scrypt.js b/lib/internal/crypto/scrypt.js index 76549c88289ecc..39305c15d8a4ba 100644 --- a/lib/internal/crypto/scrypt.js +++ b/lib/internal/crypto/scrypt.js @@ -14,6 +14,7 @@ const { } = internalBinding('crypto'); const { + validateCallback, validateInteger, validateUint32, } = require('internal/validators'); @@ -22,7 +23,6 @@ const { codes: { ERR_CRYPTO_SCRYPT_INVALID_PARAMETER, ERR_CRYPTO_SCRYPT_NOT_SUPPORTED, - ERR_INVALID_CALLBACK, } } = require('internal/errors'); @@ -50,8 +50,7 @@ function scrypt(password, salt, keylen, options, callback = defaults) { const { N, r, p, maxmem } = options; ({ password, salt, keylen } = options); - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); const job = new ScryptJob( kCryptoJobAsync, password, salt, N, r, p, maxmem, keylen); diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 6eeeb84bda9d70..e63d09713bdcca 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -18,7 +18,6 @@ const { codes: { ERR_DIR_CLOSED, ERR_DIR_CONCURRENT_OPERATION, - ERR_INVALID_CALLBACK, ERR_MISSING_ARGS } } = require('internal/errors'); @@ -32,6 +31,7 @@ const { handleErrorFromBinding } = require('internal/fs/utils'); const { + validateCallback, validateUint32 } = require('internal/validators'); @@ -87,10 +87,10 @@ class Dir { if (callback === undefined) { return this[kDirReadPromisified](); - } else if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); } + validateCallback(callback); + if (this[kDirOperationQueue] !== null) { ArrayPrototypePush(this[kDirOperationQueue], () => { this[kDirReadImpl](maybeSync, callback); @@ -174,9 +174,7 @@ class Dir { } // callback - if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } + validateCallback(callback); if (this[kDirClosed] === true) { process.nextTick(callback, new ERR_DIR_CLOSED()); @@ -236,9 +234,8 @@ ObjectDefineProperty(Dir.prototype, SymbolAsyncIterator, { function opendir(path, options, callback) { callback = typeof options === 'function' ? options : callback; - if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } + validateCallback(callback); + path = getValidatedPath(path); options = getOptions(options, { encoding: 'utf8' diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index a0251ffbafecd2..e7a0cbb436b1f5 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -44,13 +44,15 @@ const { ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED, ERR_HTTP2_STATUS_INVALID, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_INVALID_HTTP_TOKEN, ERR_STREAM_WRITE_AFTER_END }, hideStackFrames } = require('internal/errors'); -const { validateString } = require('internal/validators'); +const { + validateCallback, + validateString, +} = require('internal/validators'); const { kSocket, kRequest, @@ -784,8 +786,7 @@ class Http2ServerResponse extends Stream { } createPushResponse(headers, callback) { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(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 4fbee39c99ddf2..bc4bdeec5110b8 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -104,7 +104,6 @@ const { ERR_HTTP2_UNSUPPORTED_PROTOCOL, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_INVALID_CHAR, ERR_INVALID_HTTP_TOKEN, ERR_OUT_OF_RANGE, @@ -115,12 +114,13 @@ const { } = require('internal/errors'); const { isUint32, + validateCallback, validateInt32, validateInteger, validateNumber, validateString, validateUint32, - validateAbortSignal, + validateAbortSignal } = require('internal/validators'); const fsPromisesInternal = require('internal/fs/promises'); const { utcDate } = require('internal/http'); @@ -1309,8 +1309,7 @@ class Http2Session extends EventEmitter { if (payload && payload.length !== 8) { throw new ERR_HTTP2_PING_LENGTH(); } - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); const cb = pingCallback(callback); if (this.connecting || this.closed) { @@ -1407,8 +1406,9 @@ class Http2Session extends EventEmitter { assertIsObject(settings, 'settings'); validateSettings(settings); - if (callback && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback) { + validateCallback(callback); + } debugSessionObj(this, 'sending settings'); this[kState].pendingAck++; @@ -2204,8 +2204,9 @@ class Http2Stream extends Duplex { close(code = NGHTTP2_NO_ERROR, callback) { validateInteger(code, 'code', 0, kMaxInt); - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } if (this.closed) return; @@ -2607,8 +2608,7 @@ class ServerHttp2Stream extends Http2Stream { options = undefined; } - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); assertIsObject(options, 'options'); options = { ...options }; @@ -3048,8 +3048,7 @@ class Http2SecureServer extends TLSServer { setTimeout(msecs, callback) { this.timeout = msecs; if (callback !== undefined) { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); this.on('timeout', callback); } return this; @@ -3076,8 +3075,7 @@ class Http2Server extends NETServer { setTimeout(msecs, callback) { this.timeout = msecs; if (callback !== undefined) { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); this.on('timeout', callback); } return this; diff --git a/lib/internal/process/task_queues.js b/lib/internal/process/task_queues.js index 3cf07601a23aa4..4081acae951acd 100644 --- a/lib/internal/process/task_queues.js +++ b/lib/internal/process/task_queues.js @@ -34,11 +34,12 @@ const { symbols: { async_id_symbol, trigger_async_id_symbol } } = require('internal/async_hooks'); const { - ERR_INVALID_CALLBACK, ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; const FixedQueue = require('internal/fixed_queue'); +const { validateCallback } = require('internal/validators'); + // *Must* match Environment::TickInfo::Fields in src/env.h. const kHasTickScheduled = 0; @@ -99,8 +100,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) { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); if (process._exiting) return; diff --git a/lib/internal/stream_base_commons.js b/lib/internal/stream_base_commons.js index 0dfee0c9c7b619..5254fc1553dd77 100644 --- a/lib/internal/stream_base_commons.js +++ b/lib/internal/stream_base_commons.js @@ -17,9 +17,6 @@ const { } = internalBinding('stream_wrap'); const { UV_EOF } = internalBinding('uv'); const { - codes: { - ERR_INVALID_CALLBACK - }, errnoException } = require('internal/errors'); const { owner_symbol } = require('internal/async_hooks').symbols; @@ -30,6 +27,7 @@ const { } = require('internal/timers'); const { isUint8Array } = require('internal/util/types'); const { clearTimeout } = require('timers'); +const { validateCallback } = require('internal/validators'); const kMaybeDestroy = Symbol('kMaybeDestroy'); const kUpdateTimer = Symbol('kUpdateTimer'); @@ -259,8 +257,7 @@ function setStreamTimeout(msecs, callback) { if (msecs === 0) { if (callback !== undefined) { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); this.removeListener('timeout', callback); } } else { @@ -268,8 +265,7 @@ function setStreamTimeout(msecs, callback) { if (this[kSession]) this[kSession][kUpdateTimer](); if (callback !== undefined) { - if (typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + validateCallback(callback); this.once('timeout', callback); } } diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js index 30f8c9acf4ece9..900e561d32943c 100644 --- a/lib/internal/streams/pipeline.js +++ b/lib/internal/streams/pipeline.js @@ -17,11 +17,12 @@ const destroyImpl = require('internal/streams/destroy'); const { ERR_INVALID_ARG_TYPE, ERR_INVALID_RETURN_VALUE, - ERR_INVALID_CALLBACK, ERR_MISSING_ARGS, ERR_STREAM_DESTROYED } = require('internal/errors').codes; +const { validateCallback } = require('internal/validators'); + let EE; let PassThrough; let Readable; @@ -73,8 +74,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. - if (typeof streams[streams.length - 1] !== 'function') - throw new ERR_INVALID_CALLBACK(streams[streams.length - 1]); + validateCallback(streams[streams.length - 1]); return streams.pop(); } diff --git a/lib/internal/timers.js b/lib/internal/timers.js index 5009572f90f265..a5b5c10010e95b 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -108,10 +108,12 @@ const trigger_async_id_symbol = Symbol('triggerId'); const kHasPrimitive = Symbol('kHasPrimitive'); const { - ERR_INVALID_CALLBACK, ERR_OUT_OF_RANGE } = require('internal/errors').codes; -const { validateNumber } = require('internal/validators'); +const { + validateCallback, + validateNumber, +} = require('internal/validators'); const L = require('internal/linkedlist'); const PriorityQueue = require('internal/priority_queue'); @@ -368,9 +370,7 @@ function insert(item, msecs, start = getLibuvNow()) { function setUnrefTimeout(callback, after) { // Type checking identical to setTimeout() - if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } + validateCallback(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 d718dfa9d13d1f..900b6b03cd9ec1 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -44,7 +44,6 @@ const { ERR_ARG_NOT_ITERABLE, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_INVALID_FILE_URL_HOST, ERR_INVALID_FILE_URL_PATH, ERR_INVALID_THIS, @@ -65,6 +64,8 @@ const { } = require('internal/constants'); const path = require('path'); +const { validateCallback } = require('internal/validators'); + // Lazy loaded for startup performance. let querystring; @@ -1129,9 +1130,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { if (!this || !this[searchParams] || this[searchParams][searchParams]) { throw new ERR_INVALID_THIS('URLSearchParams'); } - if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } + validateCallback(callback); let list = this[searchParams]; diff --git a/lib/perf_hooks.js b/lib/perf_hooks.js index 7429db38fd77ef..6733992b9fae39 100644 --- a/lib/perf_hooks.js +++ b/lib/perf_hooks.js @@ -56,7 +56,6 @@ const L = require('internal/linkedlist'); const kInspect = require('internal/util').customInspectSymbol; const { - ERR_INVALID_CALLBACK, ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_VALID_PERFORMANCE_ENTRY_TYPE, @@ -68,6 +67,8 @@ const { kHandle, } = require('internal/histogram'); +const { validateCallback } = require('internal/validators'); + const { setImmediate } = require('timers'); const kCallback = Symbol('callback'); const kTypes = Symbol('types'); @@ -341,9 +342,7 @@ class PerformanceObserverEntryList { class PerformanceObserver { constructor(callback) { - if (typeof callback !== 'function') { - throw new ERR_INVALID_CALLBACK(callback); - } + validateCallback(callback); ObjectDefineProperties(this, { [kTypes]: { enumerable: false, diff --git a/lib/readline.js b/lib/readline.js index 8995fcbbf44335..085445a4e5b598 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -64,10 +64,10 @@ const { const { ERR_INVALID_ARG_VALUE, - ERR_INVALID_CALLBACK, ERR_INVALID_CURSOR_POS, } = require('internal/errors').codes; const { + validateCallback, validateString, validateUint32, } = require('internal/validators'); @@ -1216,8 +1216,9 @@ function emitKeypressEvents(stream, iface = {}) { */ function cursorTo(stream, x, y, callback) { - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } if (typeof y === 'function') { callback = y; @@ -1242,8 +1243,9 @@ function cursorTo(stream, x, y, callback) { */ function moveCursor(stream, dx, dy, callback) { - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } if (stream == null || !(dx || dy)) { if (typeof callback === 'function') @@ -1276,8 +1278,9 @@ function moveCursor(stream, dx, dy, callback) { */ function clearLine(stream, dir, callback) { - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } if (stream === null || stream === undefined) { if (typeof callback === 'function') @@ -1298,8 +1301,9 @@ function clearLine(stream, dir, callback) { */ function clearScreenDown(stream, callback) { - if (callback !== undefined && typeof callback !== 'function') - throw new ERR_INVALID_CALLBACK(callback); + if (callback !== undefined) { + validateCallback(callback); + } if (stream === null || stream === undefined) { if (typeof callback === 'function')