Skip to content

Commit 2811ce1

Browse files
committed
lib: improve error handling in Buffer.concat
- Replace ERR_INVALID_ARG_TYPE with ERR_INVALID_CONTAINER_ELEMENT_TYPE for clarity in error messages - Update test-buffer-concat.js with new error code and message format - Add new error ERR_INVALID_CONTAINER_ELEMENT_TYPE in lib/internal/errors.js - Add document for ERR_INVALID_CONTAINER_ELEMENT_TYPE in doc/api/errors.md
1 parent 6fd67ec commit 2811ce1

File tree

4 files changed

+97
-8
lines changed

4 files changed

+97
-8
lines changed

doc/api/errors.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,6 +1930,12 @@ operation.
19301930

19311931
Invalid characters were detected in headers.
19321932

1933+
<a id="ERR_INVALID_CONTAINER_ELEMENT_TYPE"></a>
1934+
1935+
### `ERR_INVALID_CONTAINER_ELEMENT_TYPE`
1936+
1937+
A container element (e.g. array, set, map, etc.) of the wrong type was passed to a Node.js API.
1938+
19331939
<a id="ERR_INVALID_CURSOR_POS"></a>
19341940

19351941
### `ERR_INVALID_CURSOR_POS`

lib/buffer.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ const {
105105
ERR_INVALID_ARG_TYPE,
106106
ERR_INVALID_ARG_VALUE,
107107
ERR_INVALID_BUFFER_SIZE,
108+
ERR_INVALID_CONTAINER_ELEMENT_TYPE,
108109
ERR_MISSING_ARGS,
109110
ERR_OUT_OF_RANGE,
110111
ERR_UNKNOWN_ENCODING,
@@ -595,10 +596,8 @@ Buffer.concat = function concat(list, length) {
595596
for (let i = 0; i < list.length; i++) {
596597
const buf = list[i];
597598
if (!isUint8Array(buf)) {
598-
// TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
599-
// Instead, find the proper error code for this.
600-
throw new ERR_INVALID_ARG_TYPE(
601-
`list[${i}]`, ['Buffer', 'Uint8Array'], list[i]);
599+
throw new ERR_INVALID_CONTAINER_ELEMENT_TYPE(
600+
'list', i, ['Buffer', 'Uint8Array'], list[i]);
602601
}
603602
pos += _copyActual(buf, buffer, pos, 0, buf.length);
604603
}

lib/internal/errors.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,90 @@ E('ERR_INVALID_CHAR',
14801480
if (field !== undefined) {
14811481
msg += ` ["${field}"]`;
14821482
}
1483+
return msg;
1484+
}, TypeError, HideStackFramesError);
1485+
E('ERR_INVALID_CONTAINER_ELEMENT_TYPE',
1486+
(containerName, key, expected, actual) => {
1487+
assert(typeof containerName === 'string', "'containerName' must be a string");
1488+
assert(typeof key === 'string' || typeof key === 'number' || typeof key === 'symbol',
1489+
"'key' must be a string, number, or symbol");
1490+
if (!ArrayIsArray(expected)) {
1491+
expected = [expected];
1492+
}
1493+
1494+
let elementRef;
1495+
if (typeof key === 'number') {
1496+
elementRef = `"${containerName}[${key}]"`;
1497+
} else if (typeof key === 'string') {
1498+
elementRef = `"${containerName}" element "${key}"`;
1499+
} else {
1500+
// Handle symbol keys
1501+
const symbolDesc = key.description;
1502+
const symbolStr = String(key);
1503+
if (symbolDesc !== undefined) {
1504+
elementRef = `"${containerName}" element "${symbolDesc}"`;
1505+
} else if (symbolStr === 'Symbol()') {
1506+
elementRef = `"${containerName}" element`;
1507+
} else {
1508+
const match = symbolStr.match(/^Symbol\((.+)\)$/);
1509+
elementRef = `"${containerName}" element "${match ? match[1] : symbolStr}"`;
1510+
}
1511+
}
1512+
1513+
let msg = `The ${elementRef} must be `;
1514+
1515+
const types = [];
1516+
const instances = [];
1517+
const other = [];
1518+
1519+
for (const value of expected) {
1520+
assert(typeof value === 'string',
1521+
'All expected entries have to be of type string');
1522+
if (ArrayPrototypeIncludes(kTypes, value)) {
1523+
ArrayPrototypePush(types, StringPrototypeToLowerCase(value));
1524+
} else if (RegExpPrototypeExec(classRegExp, value) !== null) {
1525+
ArrayPrototypePush(instances, value);
1526+
} else {
1527+
assert(value !== 'object',
1528+
'The value "object" should be written as "Object"');
1529+
ArrayPrototypePush(other, value);
1530+
}
1531+
}
1532+
1533+
// Special handle `object` in case other instances are allowed to outline
1534+
// the differences between each other.
1535+
if (instances.length > 0) {
1536+
const pos = ArrayPrototypeIndexOf(types, 'object');
1537+
if (pos !== -1) {
1538+
ArrayPrototypeSplice(types, pos, 1);
1539+
ArrayPrototypePush(instances, 'Object');
1540+
}
1541+
}
1542+
1543+
if (types.length > 0) {
1544+
msg += `${types.length > 1 ? 'one of type' : 'of type'} ${formatList(types, 'or')}`;
1545+
if (instances.length > 0 || other.length > 0)
1546+
msg += ' or ';
1547+
}
1548+
1549+
if (instances.length > 0) {
1550+
msg += `an instance of ${formatList(instances, 'or')}`;
1551+
if (other.length > 0)
1552+
msg += ' or ';
1553+
}
1554+
1555+
if (other.length > 0) {
1556+
if (other.length > 1) {
1557+
msg += `one of ${formatList(other, 'or')}`;
1558+
} else {
1559+
if (StringPrototypeToLowerCase(other[0]) !== other[0])
1560+
msg += 'an ';
1561+
msg += `${other[0]}`;
1562+
}
1563+
}
1564+
1565+
msg += `. Received ${determineSpecificType(actual)}`;
1566+
14831567
return msg;
14841568
}, TypeError, HideStackFramesError);
14851569
E('ERR_INVALID_CURSOR_POS',

test/parallel/test-buffer-concat.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,17 @@ assert.strictEqual(flatLongLen.toString(), check);
5858
assert.throws(() => {
5959
Buffer.concat(value);
6060
}, {
61-
code: 'ERR_INVALID_ARG_TYPE',
62-
message: 'The "list[0]" argument must be an instance of Buffer ' +
61+
code: 'ERR_INVALID_CONTAINER_ELEMENT_TYPE',
62+
message: 'The "list[0]" must be an instance of Buffer ' +
6363
`or Uint8Array.${common.invalidArgTypeHelper(value[0])}`
6464
});
6565
});
6666

6767
assert.throws(() => {
6868
Buffer.concat([Buffer.from('hello'), 3]);
6969
}, {
70-
code: 'ERR_INVALID_ARG_TYPE',
71-
message: 'The "list[1]" argument must be an instance of Buffer ' +
70+
code: 'ERR_INVALID_CONTAINER_ELEMENT_TYPE',
71+
message: 'The "list[1]" must be an instance of Buffer ' +
7272
'or Uint8Array. Received type number (3)'
7373
});
7474

0 commit comments

Comments
 (0)