Skip to content

Commit f22672d

Browse files
lundibundiMylesBorins
authored andcommittedNov 16, 2020
errors: improve ERR_INVALID_OPT_VALUE error
* use util.inspect for value presentation * allow to optionally specify error reason PR-URL: #34671 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Mary Marchini <oss@mmarchini.me>
1 parent a9a606f commit f22672d

9 files changed

+45
-26
lines changed
 

‎lib/internal/child_process.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ function getValidStdio(stdio, sync) {
908908
if (typeof stdio === 'string') {
909909
stdio = stdioStringToArray(stdio);
910910
} else if (!ArrayIsArray(stdio)) {
911-
throw new ERR_INVALID_OPT_VALUE('stdio', inspect(stdio));
911+
throw new ERR_INVALID_OPT_VALUE('stdio', stdio);
912912
}
913913

914914
// At least 3 stdio will be created
@@ -993,7 +993,7 @@ function getValidStdio(stdio, sync) {
993993
} else {
994994
// Cleanup
995995
cleanup();
996-
throw new ERR_INVALID_OPT_VALUE('stdio', inspect(stdio));
996+
throw new ERR_INVALID_OPT_VALUE('stdio', stdio);
997997
}
998998

999999
return acc;

‎lib/internal/errors.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1100,10 +1100,13 @@ E('ERR_INVALID_MODULE_SPECIFIER', (request, reason, base = undefined) => {
11001100
return `Invalid module "${request}" ${reason}${base ?
11011101
` imported from ${base}` : ''}`;
11021102
}, TypeError);
1103-
E('ERR_INVALID_OPT_VALUE', (name, value) =>
1104-
`The value "${String(value)}" is invalid for option "${name}"`,
1105-
TypeError,
1106-
RangeError);
1103+
E('ERR_INVALID_OPT_VALUE', (name, value, reason = '') => {
1104+
let inspected = typeof value === 'string' ?
1105+
value : lazyInternalUtilInspect().inspect(value);
1106+
if (inspected.length > 128) inspected = `${inspected.slice(0, 128)}...`;
1107+
if (reason) reason = '. ' + reason;
1108+
return `The value "${inspected}" is invalid for option "${name}"` + reason;
1109+
}, TypeError, RangeError);
11071110
E('ERR_INVALID_OPT_VALUE_ENCODING',
11081111
'The value "%s" is invalid for option "encoding"', TypeError);
11091112
E('ERR_INVALID_PACKAGE_CONFIG', (path, base, message) => {

‎lib/net.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ const {
3434

3535
const EventEmitter = require('events');
3636
const stream = require('stream');
37-
const { inspect } = require('internal/util/inspect');
3837
let debug = require('internal/util/debuglog').debuglog('net', (fn) => {
3938
debug = fn;
4039
});
@@ -1489,7 +1488,7 @@ Server.prototype.listen = function(...args) {
14891488
'must have the property "port" or "path"');
14901489
}
14911490

1492-
throw new ERR_INVALID_OPT_VALUE('options', inspect(options));
1491+
throw new ERR_INVALID_OPT_VALUE('options', options);
14931492
};
14941493

14951494
function lookupAndListen(self, port, address, backlog, exclusive, flags) {

‎test/parallel/test-crypto-keygen.js

+24-13
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const {
1616
sign,
1717
verify
1818
} = require('crypto');
19-
const { promisify } = require('util');
19+
const { inspect, promisify } = require('util');
2020

2121
// Asserts that the size of the given key (in chars or bytes) is within 10% of
2222
// the expected size.
@@ -705,13 +705,14 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
705705
}), {
706706
name: 'TypeError',
707707
code: 'ERR_INVALID_OPT_VALUE',
708-
message: `The value "${type}" is invalid for option ` +
708+
message: `The value "${inspect(type)}" is invalid for option ` +
709709
'"publicKeyEncoding.type"'
710710
});
711711
}
712712

713713
// Missing / invalid publicKeyEncoding.format.
714714
for (const format of [undefined, null, 0, false, 'a', {}]) {
715+
const expected = typeof format === 'string' ? format : inspect(format);
715716
assert.throws(() => generateKeyPairSync('rsa', {
716717
modulusLength: 4096,
717718
publicKeyEncoding: {
@@ -725,7 +726,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
725726
}), {
726727
name: 'TypeError',
727728
code: 'ERR_INVALID_OPT_VALUE',
728-
message: `The value "${format}" is invalid for option ` +
729+
message: `The value "${expected}" is invalid for option ` +
729730
'"publicKeyEncoding.format"'
730731
});
731732
}
@@ -761,13 +762,14 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
761762
}), {
762763
name: 'TypeError',
763764
code: 'ERR_INVALID_OPT_VALUE',
764-
message: `The value "${type}" is invalid for option ` +
765+
message: `The value "${inspect(type)}" is invalid for option ` +
765766
'"privateKeyEncoding.type"'
766767
});
767768
}
768769

769770
// Missing / invalid privateKeyEncoding.format.
770771
for (const format of [undefined, null, 0, false, 'a', {}]) {
772+
const expected = typeof format === 'string' ? format : inspect(format);
771773
assert.throws(() => generateKeyPairSync('rsa', {
772774
modulusLength: 4096,
773775
publicKeyEncoding: {
@@ -781,7 +783,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
781783
}), {
782784
name: 'TypeError',
783785
code: 'ERR_INVALID_OPT_VALUE',
784-
message: `The value "${format}" is invalid for option ` +
786+
message: `The value "${expected}" is invalid for option ` +
785787
'"privateKeyEncoding.format"'
786788
});
787789
}
@@ -802,7 +804,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
802804
}), {
803805
name: 'TypeError',
804806
code: 'ERR_INVALID_OPT_VALUE',
805-
message: `The value "${cipher}" is invalid for option ` +
807+
message: `The value "${inspect(cipher)}" is invalid for option ` +
806808
'"privateKeyEncoding.cipher"'
807809
});
808810
}
@@ -865,25 +867,29 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
865867
{
866868
// Test invalid modulus lengths.
867869
for (const modulusLength of [undefined, null, 'a', true, {}, [], 512.1, -1]) {
870+
const expected = typeof modulusLength === 'string' ?
871+
modulusLength : inspect(modulusLength);
868872
assert.throws(() => generateKeyPair('rsa', {
869873
modulusLength
870874
}), {
871875
name: 'TypeError',
872876
code: 'ERR_INVALID_OPT_VALUE',
873-
message: `The value "${modulusLength}" is invalid for option ` +
877+
message: `The value "${expected}" is invalid for option ` +
874878
'"modulusLength"'
875879
});
876880
}
877881

878882
// Test invalid exponents.
879883
for (const publicExponent of ['a', true, {}, [], 3.5, -1]) {
884+
const expected = typeof publicExponent === 'string' ?
885+
publicExponent : inspect(publicExponent);
880886
assert.throws(() => generateKeyPair('rsa', {
881887
modulusLength: 4096,
882888
publicExponent
883889
}), {
884890
name: 'TypeError',
885891
code: 'ERR_INVALID_OPT_VALUE',
886-
message: `The value "${publicExponent}" is invalid for option ` +
892+
message: `The value "${expected}" is invalid for option ` +
887893
'"publicExponent"'
888894
});
889895
}
@@ -893,25 +899,29 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
893899
{
894900
// Test invalid modulus lengths.
895901
for (const modulusLength of [undefined, null, 'a', true, {}, [], 4096.1]) {
902+
const expected = typeof modulusLength === 'string' ?
903+
modulusLength : inspect(modulusLength);
896904
assert.throws(() => generateKeyPair('dsa', {
897905
modulusLength
898906
}), {
899907
name: 'TypeError',
900908
code: 'ERR_INVALID_OPT_VALUE',
901-
message: `The value "${modulusLength}" is invalid for option ` +
909+
message: `The value "${expected}" is invalid for option ` +
902910
'"modulusLength"'
903911
});
904912
}
905913

906914
// Test invalid divisor lengths.
907915
for (const divisorLength of ['a', true, {}, [], 4096.1]) {
916+
const expected = typeof divisorLength === 'string' ?
917+
divisorLength : inspect(divisorLength);
908918
assert.throws(() => generateKeyPair('dsa', {
909919
modulusLength: 2048,
910920
divisorLength
911921
}), {
912922
name: 'TypeError',
913923
code: 'ERR_INVALID_OPT_VALUE',
914-
message: `The value "${divisorLength}" is invalid for option ` +
924+
message: `The value "${expected}" is invalid for option ` +
915925
'"divisorLength"'
916926
});
917927
}
@@ -942,7 +952,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
942952
}, {
943953
name: 'TypeError',
944954
code: 'ERR_INVALID_OPT_VALUE',
945-
message: `The value "${namedCurve}" is invalid for option ` +
955+
message: `The value "${inspect(namedCurve)}" is invalid for option ` +
946956
'"namedCurve"'
947957
});
948958
}
@@ -1079,7 +1089,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
10791089
}, {
10801090
name: 'TypeError',
10811091
code: 'ERR_INVALID_OPT_VALUE',
1082-
message: `The value "${hashValue}" is invalid for option "hash"`
1092+
message: `The value "${inspect(hashValue)}" is invalid for option "hash"`
10831093
});
10841094
}
10851095

@@ -1182,6 +1192,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
11821192
);
11831193

11841194
for (const mgf1Hash of [null, 0, false, {}, []]) {
1195+
const expected = inspect(mgf1Hash);
11851196
assert.throws(
11861197
() => {
11871198
generateKeyPair('rsa-pss', {
@@ -1194,7 +1205,7 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher);
11941205
{
11951206
name: 'TypeError',
11961207
code: 'ERR_INVALID_OPT_VALUE',
1197-
message: `The value "${mgf1Hash}" is invalid for option "mgf1Hash"`
1208+
message: `The value "${expected}" is invalid for option "mgf1Hash"`
11981209
}
11991210
);
12001211
}

‎test/parallel/test-http2-client-request-options-errors.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 http2 = require('http2');
8+
const { inspect } = require('util');
89

910
// Check if correct errors are emitted when wrong type of data is passed
1011
// to certain options of ClientHttp2Session request method
@@ -48,7 +49,7 @@ server.listen(0, common.mustCall(() => {
4849
}), {
4950
name: 'TypeError',
5051
code: 'ERR_INVALID_OPT_VALUE',
51-
message: `The value "${String(types[type])}" is invalid ` +
52+
message: `The value "${inspect(types[type])}" is invalid ` +
5253
`for option "${option}"`
5354
});
5455
});

‎test/parallel/test-http2-respond-file-errors.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ if (!common.hasCrypto)
66
const fixtures = require('../common/fixtures');
77
const assert = require('assert');
88
const http2 = require('http2');
9+
const { inspect } = require('util');
910

1011
const optionsWithTypeError = {
1112
offset: 'number',
@@ -45,7 +46,7 @@ server.on('stream', common.mustCall((stream) => {
4546
{
4647
name: 'TypeError',
4748
code: 'ERR_INVALID_OPT_VALUE',
48-
message: `The value "${String(types[type])}" is invalid ` +
49+
message: `The value "${inspect(types[type])}" is invalid ` +
4950
`for option "${option}"`
5051
}
5152
);

‎test/parallel/test-http2-respond-file-fd-errors.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const fixtures = require('../common/fixtures');
77
const assert = require('assert');
88
const http2 = require('http2');
99
const fs = require('fs');
10+
const { inspect } = require('util');
1011

1112
const optionsWithTypeError = {
1213
offset: 'number',
@@ -65,7 +66,7 @@ server.on('stream', common.mustCall((stream) => {
6566
{
6667
name: 'TypeError',
6768
code: 'ERR_INVALID_OPT_VALUE',
68-
message: `The value "${String(types[type])}" is invalid ` +
69+
message: `The value "${inspect(types[type])}" is invalid ` +
6970
`for option "${option}"`
7071
}
7172
);

‎test/parallel/test-performanceobserver.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_FUNCTION], 0);
5858
{
5959
code: 'ERR_INVALID_OPT_VALUE',
6060
name: 'TypeError',
61-
message: `The value "${i}" is invalid ` +
61+
message: `The value "${inspect(i)}" is invalid ` +
6262
'for option "entryTypes"'
6363
});
6464
});

‎test/parallel/test-streams-highwatermark.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const common = require('../common');
33

44
const assert = require('assert');
55
const stream = require('stream');
6+
const { inspect } = require('util');
67

78
{
89
// This test ensures that the stream implementation correctly handles values
@@ -20,14 +21,16 @@ const stream = require('stream');
2021
assert.strictEqual(writable._writableState.highWaterMark, ovfl);
2122

2223
for (const invalidHwm of [true, false, '5', {}, -5, NaN]) {
24+
const expected = typeof invalidHwm === 'string' ?
25+
invalidHwm : inspect(invalidHwm);
2326
for (const type of [stream.Readable, stream.Writable]) {
2427
assert.throws(() => {
2528
type({ highWaterMark: invalidHwm });
2629
}, {
2730
name: 'TypeError',
2831
code: 'ERR_INVALID_OPT_VALUE',
2932
message:
30-
`The value "${invalidHwm}" is invalid for option "highWaterMark"`
33+
`The value "${expected}" is invalid for option "highWaterMark"`
3134
});
3235
}
3336
}

0 commit comments

Comments
 (0)
Please sign in to comment.