8000 buffer,errors: improve bigint, big numbers and more · nodejs/node@cac584d · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit cac584d

Browse files
BridgeARtargos
authored andcommitted
buffer,errors: improve bigint, big numbers and more
This improves the error message from `ERR_OUT_OF_RANGE` by closer inspecting the value and logging numbers above 2 ** 32 by adding commas to the output for integer and bigint. BigInt is now also marked if used. Buffer errors also format the range as 2 ** n instead of showing a huge number. PR-URL: #27228 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaël Zasso <targos@protonmail.com>
1 parent cb97de7 commit cac584d

8 files changed

+65
-13
lines changed

lib/internal/buffer.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,20 @@ function checkBounds(buf, offset, byteLength) {
4343

4444
function checkInt(value, min, max, buf, offset, byteLength) {
4545
if (value > max || value < min) {
46-
throw new ERR_OUT_OF_RANGE('value', `>= ${min} and <= ${max}`, value);
46+
// eslint-disable-next-line valid-typeof
47+
const n = typeof min === 'bigint' ? 'n' : '';
48+
let range;
49+
if (byteLength > 3) {
50+
if (min === 0 || min === 0n) {
51+
range = `>= 0${n} and < 2${n} ** ${(byteLength + 1) * 8}${n}`;
52+
} else {
53+
range = `>= -(2${n} ** ${(byteLength + 1) * 8 - 1}${n}) and < 2 ** ` +
54+
`${(byteLength + 1) * 8 - 1}${n}`;
55+
}
56+
} else {
57+
range = `>= ${min}${n} and <= ${max}${n}`;
58+
}
59+
throw new ERR_OUT_OF_RANGE('value', range, value);
4760
}
4861
checkBounds(buf, offset, byteLength);
4962
}

lib/internal/errors.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// value statically and permanently identifies the error. While the error
1111
// message may change, the code should not.
1212

13-
const { Object } = primordials;
13+
const { Object, Math } = primordials;
1414

1515
const kCode = Symbol('code');
1616
const kInfo = Symbol('info');
@@ -574,6 +574,17 @@ function oneOf(expected, thing) {
574574
}
575575
}
576576

577+
// Only use this for integers! Decimal numbers do not work with this function.
578+
function addNumericalSeparator(val) {
579+
let res = '';
580+
let i = val.length;
581+
const start = val[0] === '-' ? 1 : 0;
582+
for (; i >= start + 4; i -= 3) {
583+
res = `_${val.slice(i - 3, i)}${res}`;
584+
}
585+
return `${val.slice(0, i)}${res}`;
586+
}
587+
577588
module.exports = {
578589
addCodeToName, // Exported for NghttpError
579590
codes,
@@ -990,7 +1001,20 @@ E('ERR_OUT_OF_RANGE',
9901001
assert(range, 'Missing "range" argument');
9911002
let msg = replaceDefaultBoolean ? str :
9921003
`The value of "${str}" is out of range.`;
993-
msg += ` It must be ${range}. Received ${input}`;
1004+
let received;
1005+
if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {
1006+
received = addNumericalSeparator(String(input));
1007+
// eslint-disable-next-line valid-typeof
1008+
} else if (typeof input === 'bigint') {
1009+
received = String(input);
1010+
if (input > 2n ** 32n || input < -(2n ** 32n)) {
1011+
received = addNumericalSeparator(received);
1012+
}
1013+
received += 'n';
1014+
} else {
1015+
received = lazyInternalUtilInspect().inspect(input);
1016+
}
1017+
msg += ` It must be ${range}. Received ${received}`;
9941018
return msg;
9951019
}, RangeError);
9961020
E('ERR_REQUIRE_ESM', 'Must use import to load ES Module: %s', Error);

test/parallel/test-buffer-bigint64.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ const buf = Buffer.allocUnsafe(8);
3737
assert.throws(function() {
3838
const val = 0x10000000000000000n;
3939
buf['writeBigUInt64' + endianness](val, 0);
40-
}, RangeError);
40+
}, {
41+
code: 'ERR_OUT_OF_RANGE',
42+
message: 'The value of "value" is out of range. It must be ' +
43+
'>= 0n and < 2n ** 64n. Received 18_446_744_073_709_551_616n'
44+
});
4145

4246
// Should throw a TypeError upon invalid input
4347
assert.throws(function() {

test/parallel/test-buffer-writeint.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,21 @@ const errorOutOfBounds = common.expectsError({
217217
['writeIntBE', 'writeIntLE'].forEach((fn) => {
218218
const min = -(2 ** (i * 8 - 1));
219219
const max = 2 ** (i * 8 - 1) - 1;
220-
220+
let range = `>= ${min} and <= ${max}`;
221+
if (i > 4) {
222+
range = `>= -(2 ** ${i * 8 - 1}) and < 2 ** ${i * 8 - 1}`;
223+
}
221224
[min - 1, max + 1].forEach((val) => {
225+
const received = i > 4 ?
226+
String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') :
227+
val;
222228
assert.throws(() => {
223229
data[fn](val, 0, i);
224230
}, {
225231
code: 'ERR_OUT_OF_RANGE',
226232
name: 'RangeError',
227233
message: 'The value of "value" is out of range. ' +
228-
`It must be >= ${min} and <= ${max}. Received ${val}`
234+
`It must be ${range}. Received ${received}`
229235
});
230236
});
231237

test/parallel/test-buffer-writeuint.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,18 @@ const assert = require('assert');
171171

172172
// Test 1 to 6 bytes.
173173
for (let i = 1; i < 6; i++) {
174+
const range = i < 5 ? `= ${val - 1}` : ` 2 ** ${i * 8}`;
175+
const received = i > 4 ?
176+
String(val).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1_') :
177+
val;
174178
['writeUIntBE', 'writeUIntLE'].forEach((fn) => {
175179
assert.throws(() => {
176180
data[fn](val, 0, i);
177181
}, {
178182
code: 'ERR_OUT_OF_RANGE',
179183
name: 'RangeError',
180184
message: 'The value of "value" is out of range. ' +
181-
`It must be >= 0 and <= ${val - 1}. Received ${val}`
185+
`It must be >= 0 and <${range}. Received ${received}`
182186
});
183187

184188
['', '0', null, {}, [], () => {}, true, false].forEach((o) => {

test/parallel/test-crypto-pbkdf2.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ assert.throws(
111111
}, {
112112
code: 'ERR_OUT_OF_RANGE',
113113
name: 'RangeError',
114-
message: 'The value of "keylen" is out of range. It ' +
115-
`must be >= 0 && < 4294967296. Received ${input}`
114+
message: 'The value of "keylen" is out of range. It must be >= 0 && < ' +
115+
`4294967296. Received ${input === -1 ? '-1' : '4_294_967_297'}`
116116
});
117117
});
118118

test/parallel/test-event-emitter-max-listeners.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'use strict';
2323
const common = require('../common');
2424
const events = require('events');
25+
const { inspect } = require('util');
2526
const e = new events.EventEmitter();
2627

2728
e.on('maxListeners', common.mustCall());
@@ -38,7 +39,7 @@ for (const obj of throwsObjs) {
3839
code: 'ERR_OUT_OF_RANGE',
3940
type: RangeError,
4041
message: 'The value of "n" is out of range. ' +
41-
`It must be a non-negative number. Received ${obj}`
42+
`It must be a non-negative number. Received ${inspect(obj)}`
4243
}
4344
);
4445

@@ -48,7 +49,7 @@ for (const obj of throwsObjs) {
4849
code: 'ERR_OUT_OF_RANGE',
4950
type: RangeError,
5051
message: 'The value of "defaultMaxListeners" is out of range. ' +
51-
`It must be a non-negative number. Received ${obj}`
52+
`It must be a non-negative number. Received ${inspect(obj)}`
5253
}
5354
);
5455
}

test/parallel/test-file-write-stream3.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ const run_test_5 = common.mustCall(function() {
199199
};
200200
const err = {
201201
code: 'ERR_OUT_OF_RANGE',
202-
message: 'The value of "start" is out of range. ' +
203-
'It must be >= 0 and <= 2 ** 53 - 1. Received 9007199254740992',
202+
message: 'The value of "start" is out of range. It must be ' +
203+
'>= 0 and <= 2 ** 53 - 1. Received 9_007_199_254_740_992',
204204
type: RangeError
205205
};
206206
common.expectsError(fn, err);

0 commit comments

Comments
 (0)
0