lib: refactor to use validateCallback

PR-URL: https://github.com/nodejs/node/pull/36609
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
ZiJian Liu
2020-12-23 19:22:00 +08:00
committed by Node.js GitHub Bot
parent 8cf5ae07e9
commit b00bb01db9
20 changed files with 114 additions and 125 deletions

View File

@@ -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',

View File

@@ -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;

View File

@@ -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');

View File

@@ -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]) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);

View File

@@ -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'

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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];

View File

@@ -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,

View File

@@ -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');
@@ -1229,8 +1229,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;
@@ -1260,8 +1261,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')
@@ -1294,8 +1296,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')
@@ -1316,8 +1319,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')