Skip to content

Commit 3b04496

Browse files
committed
errors: add more information in case of invalid callbacks
This adds the actual callback that is passed through to the error message in case an ERR_INVALID_CALLBACK error is thrown. PR-URL: #27048 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Yongsheng Zhang <[email protected]>
1 parent a9bf665 commit 3b04496

32 files changed

+90
-73
lines changed

lib/_tls_wrap.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ TLSSocket.prototype.renegotiate = function(options, callback) {
633633
if (options === null || typeof options !== 'object')
634634
throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
635635
if (callback !== undefined && typeof callback !== 'function')
636-
throw new ERR_INVALID_CALLBACK();
636+
throw new ERR_INVALID_CALLBACK(callback);
637637

638638
debug('%s renegotiate()',
639639
this._tlsOptions.isServer ? 'server' : 'client',

lib/dns.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ function lookup(hostname, options, callback) {
9898
callback = options;
9999
family = 0;
100100
} else if (typeof callback !== 'function') {
101-
throw new ERR_INVALID_CALLBACK();
101+
throw new ERR_INVALID_CALLBACK(callback);
102102
} else if (options !== null && typeof options === 'object') {
103103
hints = options.hints >>> 0;
104104
family = options.family >>> 0;
@@ -174,7 +174,7 @@ function lookupService(hostname, port, callback) {
174174
throw new ERR_SOCKET_BAD_PORT(port);
175175

176176
if (typeof callback !== 'function')
177-
throw new ERR_INVALID_CALLBACK();
177+
throw new ERR_INVALID_CALLBACK(callback);
178178

179179
port = +port;
180180

@@ -213,7 +213,7 @@ function resolver(bindingName) {
213213

214214
validateString(name, 'name');
215215
if (typeof callback !== 'function') {
216-
throw new ERR_INVALID_CALLBACK();
216+
throw new ERR_INVALID_CALLBACK(callback);
217217
}
218218

219219
const req = new QueryReqWrap();

lib/fs.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ function maybeCallback(cb) {
137137
if (typeof cb === 'function')
138138
return cb;
139139

140-
throw new ERR_INVALID_CALLBACK();
140+
throw new ERR_INVALID_CALLBACK(cb);
141141
}
142142

143143
// Ensure that callbacks run in the global context. Only use this function
144144
// for callbacks that are passed to the binding layer, callbacks that are
145145
// invoked from JS already run in the proper scope.
146146
function makeCallback(cb) {
147147
if (typeof cb !== 'function') {
148-
throw new ERR_INVALID_CALLBACK();
148+
throw new ERR_INVALID_CALLBACK(cb);
149149
}
150150

151151
return (...args) => {
@@ -158,7 +158,7 @@ function makeCallback(cb) {
158158
// transformed anyway.
159159
function makeStatsCallback(cb) {
160160
if (typeof cb !== 'function') {
161-
throw new ERR_INVALID_CALLBACK();
161+
throw new ERR_INVALID_CALLBACK(cb);
162162
}
163163

164164
return (err, stats) => {
@@ -1749,7 +1749,7 @@ function copyFile(src, dest, flags, callback) {
17491749
callback = flags;
17501750
flags = 0;
17511751
} else if (typeof callback !== 'function') {
1752-
throw new ERR_INVALID_CALLBACK();
1752+
throw new ERR_INVALID_CALLBACK(callback);
17531753
}
17541754

17551755
src = toPathIfFileURL(src);

lib/inspector.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class Session extends EventEmitter {
7878
throw new ERR_INVALID_ARG_TYPE('params', 'Object', params);
7979
}
8080
if (callback && typeof callback !== 'function') {
81-
throw new ERR_INVALID_CALLBACK();
81+
throw new ERR_INVALID_CALLBACK(callback);
8282
}
8383

8484
if (!this[connectionSymbol]) {

lib/internal/crypto/keygen.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function generateKeyPair(type, options, callback) {
4646
const impl = check(type, options);
4747

4848
if (typeof callback !== 'function')
49-
throw new ERR_INVALID_CALLBACK();
49+
throw new ERR_INVALID_CALLBACK(callback);
5050

5151
const wrap = new AsyncWrap(Providers.KEYPAIRGENREQUEST);
5252
wrap.ondone = (ex, pubkey, privkey) => {

lib/internal/crypto/pbkdf2.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function pbkdf2(password, salt, iterations, keylen, digest, callback) {
2626
check(password, salt, iterations, keylen, digest));
2727

2828
if (typeof callback !== 'function')
29-
throw new ERR_INVALID_CALLBACK();
29+
throw new ERR_INVALID_CALLBACK(callback);
3030

3131
const encoding = getDefaultEncoding();
3232
const keybuf = Buffer.alloc(keylen);

lib/internal/crypto/random.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function assertSize(size, elementSize, offset, length) {
4747
function randomBytes(size, cb) {
4848
size = assertSize(size, 1, 0, Infinity);
4949
if (cb !== undefined && typeof cb !== 'function')
50-
throw new ERR_INVALID_CALLBACK();
50+
throw new ERR_INVALID_CALLBACK(cb);
5151

5252
const buf = Buffer.alloc(size);
5353

@@ -95,7 +95,7 @@ function randomFill(buf, offset, size, cb) {
9595
cb = size;
9696
size = buf.byteLength - offset;
9797
} else if (typeof cb !== 'function') {
98-
throw new ERR_INVALID_CALLBACK();
98+
throw new ERR_INVALID_CALLBACK(cb);
9999
}
100100

101101
offset = assertOffset(offset, elementSize, buf.byteLength);

lib/internal/crypto/scrypt.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function scrypt(password, salt, keylen, options, callback = defaults) {
3232
({ password, salt, keylen } = options);
3333

3434
if (typeof callback !== 'function')
35-
throw new ERR_INVALID_CALLBACK();
35+
throw new ERR_INVALID_CALLBACK(callback);
3636

3737
const encoding = getDefaultEncoding();
3838
const keybuf = Buffer.alloc(keylen);

lib/internal/errors.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,8 @@ E('ERR_INVALID_ARG_VALUE', (name, value, reason = 'is invalid') => {
854854
E('ERR_INVALID_ASYNC_ID', 'Invalid %s value: %s', RangeError);
855855
E('ERR_INVALID_BUFFER_SIZE',
856856
'Buffer size must be a multiple of %s', RangeError);
857-
E('ERR_INVALID_CALLBACK', 'Callback must be a function', TypeError);
857+
E('ERR_INVALID_CALLBACK',
858+
'Callback must be a function. Received %O', TypeError);
858859
E('ERR_INVALID_CHAR',
859860
// Using a default argument here is important so the argument is not counted
860861
// towards `Function#length`.

lib/internal/http2/compat.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ class Http2ServerResponse extends Stream {
701701

702702
createPushResponse(headers, callback) {
703703
if (typeof callback !== 'function')
704-
throw new ERR_INVALID_CALLBACK();
704+
throw new ERR_INVALID_CALLBACK(callback);
705705
if (this[kState].closed) {
706706
process.nextTick(callback, new ERR_HTTP2_INVALID_STREAM());
707707
return;

lib/internal/http2/core.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ class Http2Session extends EventEmitter {
10581058
throw new ERR_HTTP2_PING_LENGTH();
10591059
}
10601060
if (typeof callback !== 'function')
1061-
throw new ERR_INVALID_CALLBACK();
1061+
throw new ERR_INVALID_CALLBACK(callback);
10621062

10631063
const cb = pingCallback(callback);
10641064
if (this.connecting || this.closed) {
@@ -1148,7 +1148,7 @@ class Http2Session extends EventEmitter {
11481148
validateSettings(settings);
11491149

11501150
if (callback && typeof callback !== 'function')
1151-
throw new ERR_INVALID_CALLBACK();
1151+
throw new ERR_INVALID_CALLBACK(callback);
11521152
debug(`Http2Session ${sessionName(this[kType])}: sending settings`);
11531153

11541154
this[kState].pendingAck++;
@@ -1900,7 +1900,7 @@ class Http2Stream extends Duplex {
19001900
if (code < 0 || code > kMaxInt)
19011901
throw new ERR_OUT_OF_RANGE('code', `>= 0 && <= ${kMaxInt}`, code);
19021902
if (callback !== undefined && typeof callback !== 'function')
1903-
throw new ERR_INVALID_CALLBACK();
1903+
throw new ERR_INVALID_CALLBACK(callback);
19041904

19051905
if (this.closed)
19061906
return;
@@ -2256,7 +2256,7 @@ class ServerHttp2Stream extends Http2Stream {
22562256
}
22572257

22582258
if (typeof callback !== 'function')
2259-
throw new ERR_INVALID_CALLBACK();
2259+
throw new ERR_INVALID_CALLBACK(callback);
22602260

22612261
assertIsObject(options, 'options');
22622262
options = { ...options };
@@ -2690,7 +2690,7 @@ class Http2SecureServer extends TLSServer {
26902690
this.timeout = msecs;
26912691
if (callback !== undefined) {
26922692
if (typeof callback !== 'function')
2693-
throw new ERR_INVALID_CALLBACK();
2693+
throw new ERR_INVALID_CALLBACK(callback);
26942694
this.on('timeout', callback);
26952695
}
26962696
return this;
@@ -2711,7 +2711,7 @@ class Http2Server extends NETServer {
27112711
this.timeout = msecs;
27122712
if (callback !== undefined) {
27132713
if (typeof callback !== 'function')
2714-
throw new ERR_INVALID_CALLBACK();
2714+
throw new ERR_INVALID_CALLBACK(callback);
27152715
this.on('timeout', callback);
27162716
}
27172717
return this;

lib/internal/process/task_queues.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class TickObject {
115115
// exit since the callback would not have a chance to be executed.
116116
function nextTick(callback) {
117117
if (typeof callback !== 'function')
118-
throw new ERR_INVALID_CALLBACK();
118+
throw new ERR_INVALID_CALLBACK(callback);
119119

120120
if (process._exiting)
121121
return;

lib/internal/stream_base_commons.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ function setStreamTimeout(msecs, callback) {
214214
if (msecs === 0) {
215215
if (callback !== undefined) {
216216
if (typeof callback !== 'function')
217-
throw new ERR_INVALID_CALLBACK();
217+
throw new ERR_INVALID_CALLBACK(callback);
218218
this.removeListener('timeout', callback);
219219
}
220220
} else {
@@ -223,7 +223,7 @@ function setStreamTimeout(msecs, callback) {
223223

224224
if (callback !== undefined) {
225225
if (typeof callback !== 'function')
226-
throw new ERR_INVALID_CALLBACK();
226+
throw new ERR_INVALID_CALLBACK(callback);
227227
this.once('timeout', callback);
228228
}
229229
}

lib/internal/streams/pipeline.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function popCallback(streams) {
5858
// a single stream. Therefore optimize for the average case instead of
5959
// checking for length === 0 as well.
6060
if (typeof streams[streams.length - 1] !== 'function')
61-
throw new ERR_INVALID_CALLBACK();
61+
throw new ERR_INVALID_CALLBACK(streams[streams.length - 1]);
6262
return streams.pop();
6363
}
6464

lib/internal/timers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ function insert(item, refed, start) {
351351
function setUnrefTimeout(callback, after) {
352352
// Type checking identical to setTimeout()
353353
if (typeof callback !== 'function') {
354-
throw new ERR_INVALID_CALLBACK();
354+
throw new ERR_INVALID_CALLBACK(callback);
355355
}
356356

357357
const timer = new Timeout(callback, after, undefined, false);

lib/internal/url.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
10921092
throw new ERR_INVALID_THIS('URLSearchParams');
10931093
}
10941094
if (typeof callback !== 'function') {
1095-
throw new ERR_INVALID_CALLBACK();
1095+
throw new ERR_INVALID_CALLBACK(callback);
10961096
}
10971097

10981098
let list = this[searchParams];

lib/perf_hooks.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ let gcTrackingIsEnabled = false;
283283
class PerformanceObserver extends AsyncResource {
284284
constructor(callback) {
285285
if (typeof callback !== 'function') {
286-
throw new ERR_INVALID_CALLBACK();
286+
throw new ERR_INVALID_CALLBACK(callback);
287287
}
288288
super('PerformanceObserver');
289289
Object.defineProperties(this, {

lib/timers.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function enroll(item, msecs) {
122122

123123
function setTimeout(callback, after, arg1, arg2, arg3) {
124124
if (typeof callback !== 'function') {
125-
throw new ERR_INVALID_CALLBACK();
125+
throw new ERR_INVALID_CALLBACK(callback);
126126
}
127127

128128
var i, args;
@@ -168,7 +168,7 @@ function clearTimeout(timer) {
168168

169169
function setInterval(callback, repeat, arg1, arg2, arg3) {
170170
if (typeof callback !== 'function') {
171-
throw new ERR_INVALID_CALLBACK();
171+
throw new ERR_INVALID_CALLBACK(callback);
172172
}
173173

174174
var i, args;
@@ -255,7 +255,7 @@ const Immediate = class Immediate {
255255

256256
function setImmediate(callback, arg1, arg2, arg3) {
257257
if (typeof callback !== 'function') {
258-
throw new ERR_INVALID_CALLBACK();
258+
throw new ERR_INVALID_CALLBACK(callback);
259259
}
260260

261261
var i, args;

test/parallel/test-crypto-random.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ if (!common.hasCrypto)
2929
const assert = require('assert');
3030
const crypto = require('crypto');
3131
const { kMaxLength } = require('buffer');
32+
const { inspect } = require('util');
3233

3334
const kMaxUint32 = Math.pow(2, 32) - 1;
3435
const kMaxPossibleLength = Math.min(kMaxLength, kMaxUint32);
@@ -292,7 +293,7 @@ assert.throws(
292293
{
293294
code: 'ERR_INVALID_CALLBACK',
294295
type: TypeError,
295-
message: 'Callback must be a function',
296+
message: `Callback must be a function. Received ${inspect(i)}`
296297
});
297298
});
298299

@@ -302,7 +303,7 @@ assert.throws(
302303
{
303304
code: 'ERR_INVALID_CALLBACK',
304305
type: TypeError,
305-
message: 'Callback must be a function',
306+
message: `Callback must be a function. Received ${inspect(i)}`
306307
}
307308
);
308309
});

test/parallel/test-fs-read.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ test(new Uint8Array(expected.length),
7171
assert.throws(
7272
() => fs.read(fd, Buffer.alloc(1), 0, 1, 0),
7373
{
74-
message: 'Callback must be a function',
74+
message: 'Callback must be a function. Received undefined',
7575
code: 'ERR_INVALID_CALLBACK',
7676
}
7777
);

test/parallel/test-http2-client-rststream-before-connect.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ if (!common.hasCrypto)
55
common.skip('missing crypto');
66
const assert = require('assert');
77
const h2 = require('http2');
8+
const { inspect } = require('util');
89

910
const server = h2.createServer();
1011
server.on('stream', (stream) => {
@@ -35,7 +36,7 @@ server.listen(0, common.mustCall(() => {
3536
{
3637
type: TypeError,
3738
code: 'ERR_INVALID_CALLBACK',
38-
message: 'Callback must be a function'
39+
message: `Callback must be a function. Received ${inspect(notFunction)}`
3940
}
4041
);
4142
assert.strictEqual(req.closed, false);

test/parallel/test-http2-client-settings-before-connect.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const common = require('../common');
44
if (!common.hasCrypto)
55
common.skip('missing crypto');
66
const h2 = require('http2');
7+
const { inspect } = require('util');
78

89
const server = h2.createServer();
910

@@ -51,7 +52,8 @@ server.listen(0, common.mustCall(() => {
5152
{
5253
type: TypeError,
5354
code: 'ERR_INVALID_CALLBACK',
54-
message: 'Callback must be a function'
55+
message:
56+
`Callback must be a function. Received ${inspect(invalidCallback)}`
5557
}
5658
)
5759
);

test/parallel/test-http2-compat-serverresponse-createpushresponse.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const server = h2.createServer((request, response) => {
2424
{
2525
code: 'ERR_INVALID_CALLBACK',
2626
type: TypeError,
27-
message: 'Callback must be a function'
27+
message: 'Callback must be a function. Received undefined'
2828
}
2929
);
3030

test/parallel/test-http2-ping.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ if (!common.hasCrypto)
77
const async_hooks = require('async_hooks');
88
const assert = require('assert');
99
const http2 = require('http2');
10+
const { inspect } = require('util');
1011

1112
const pings = new Set();
1213
const events = [0, 0, 0, 0];
@@ -119,7 +120,8 @@ server.listen(0, common.mustCall(() => {
119120
{
120121
type: TypeError,
121122
code: 'ERR_INVALID_CALLBACK',
122-
message: 'Callback must be a function'
123+
message: 'Callback must be a function. ' +
124+
`Received ${inspect(invalidCallback)}`
123125
}
124126
)
125127
);

test/parallel/test-http2-server-push-stream-errors-args.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ server.on('stream', common.mustCall((stream, headers) => {
2222
}, {}, 'callback'),
2323
{
2424
code: 'ERR_INVALID_CALLBACK',
25-
message: 'Callback must be a function'
25+
message: "Callback must be a function. Received 'callback'"
2626
}
2727
);
2828

0 commit comments

Comments
 (0)