Skip to content

Commit dbfe8c4

Browse files
starkwangrefack
authored andcommitted
errors,buffer: port errors to internal/errors
PR-URL: #13976 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent 1562fb9 commit dbfe8c4

28 files changed

+344
-145
lines changed

doc/api/errors.md

+22
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,11 @@ Used as special type of error that can be triggered whenever Node.js detects an
575575
exceptional logic violation that should never occur. These are raised typically
576576
by the `assert` module.
577577

578+
<a id="ERR_BUFFER_OUT_OF_BOUNDS"></a>
579+
### ERR_BUFFER_OUT_OF_BOUNDS
580+
581+
Used when attempting to perform an operation outside the bounds of a `Buffer`.
582+
578583
<a id="ERR_CONSOLE_WRITABLE_STREAM"></a>
579584
### ERR_CONSOLE_WRITABLE_STREAM
580585

@@ -625,6 +630,11 @@ to a Node.js API.
625630

626631
Used when an Array is not of the expected length or in a valid range.
627632

633+
<a id="ERR_INVALID_BUFFER_SIZE"></a>
634+
### ERR_INVALID_BUFFER_SIZE
635+
636+
Used when performing a swap on a `Buffer` but it's size is not compatible with the operation.
637+
628638
<a id="ERR_INVALID_CALLBACK"></a>
629639
### ERR_INVALID_CALLBACK
630640

@@ -781,6 +791,13 @@ would be possible by calling a callback more then once.
781791
Used when an attempt is made to use crypto features while Node.js is not
782792
compiled with OpenSSL crypto support.
783793

794+
<a id="ERR_NO_LONGER_SUPPORTED"></a>
795+
### ERR_NO_LONGER_SUPPORTED
796+
797+
Used when a Node.js API is called in an unsupported manner.
798+
799+
For example: `Buffer.write(string, encoding, offset[, length])`
800+
784801
<a id="ERR_PARSE_HISTORY_DATA"></a>
785802
### ERR_PARSE_HISTORY_DATA
786803

@@ -844,6 +861,11 @@ Used to identify a specific kind of internal Node.js error that should not
844861
typically be triggered by user code. Instances of this error point to an
845862
internal bug within the Node.js binary itself.
846863

864+
<a id="ERR_UNKNOWN_ENCODING"></a>
865+
### ERR_UNKNOWN_ENCODING
866+
867+
Used when an invalid or unknown encoding option is passed to an API.
868+
847869
<a id="ERR_UNKNOWN_SIGNAL"></a>
848870
### ERR_UNKNOWN_SIGNAL
849871

lib/buffer.js

+40-39
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ Object.defineProperty(exports, 'constants', {
6767

6868
exports.kStringMaxLength = binding.kStringMaxLength;
6969

70-
const kFromErrorMsg = 'First argument must be a string, Buffer, ' +
71-
'ArrayBuffer, Array, or array-like object.';
72-
7370
Buffer.poolSize = 8 * 1024;
7471
var poolSize, poolOffset, allocPool;
7572

@@ -146,9 +143,8 @@ function Buffer(arg, encodingOrOffset, length) {
146143
// Common case.
147144
if (typeof arg === 'number') {
148145
if (typeof encodingOrOffset === 'string') {
149-
throw new Error(
150-
'If encoding is specified then the first argument must be a string'
151-
);
146+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'string',
147+
'string', arg);
152148
}
153149
return Buffer.alloc(arg);
154150
}
@@ -177,10 +173,12 @@ Buffer.from = function(value, encodingOrOffset, length) {
177173
return fromArrayBuffer(value, encodingOrOffset, length);
178174

179175
if (value == null)
180-
throw new TypeError(kFromErrorMsg);
176+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'first argument',
177+
['string', 'buffer', 'arrayBuffer', 'array', 'array-like object'], value);
181178

182179
if (typeof value === 'number')
183-
throw new TypeError('"value" argument must not be a number');
180+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'value', 'not number',
181+
value);
184182

185183
const valueOf = value.valueOf && value.valueOf();
186184
if (valueOf != null && valueOf !== value)
@@ -196,7 +194,8 @@ Buffer.from = function(value, encodingOrOffset, length) {
196194
length);
197195
}
198196

199-
throw new TypeError(kFromErrorMsg);
197+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'first argument',
198+
['string', 'buffer', 'arrayBuffer', 'array', 'array-like object']);
200199
};
201200

202201
Object.setPrototypeOf(Buffer, Uint8Array);
@@ -208,12 +207,11 @@ function assertSize(size) {
208207
let err = null;
209208

210209
if (typeof size !== 'number') {
211-
err = new TypeError('"size" argument must be a number');
210+
err = new errors.TypeError('ERR_INVALID_ARG_TYPE', 'size', 'number', size);
212211
} else if (size < 0) {
213-
err = new RangeError('"size" argument must not be negative');
212+
err = new errors.RangeError('ERR_INVALID_OPT_VALUE', 'size', size);
214213
} else if (size > binding.kMaxLength) {
215-
err = new RangeError('"size" argument must not be larger ' +
216-
'than ' + binding.kMaxLength);
214+
err = new errors.RangeError('ERR_INVALID_OPT_VALUE', 'size', size);
217215
}
218216

219217
if (err) {
@@ -300,7 +298,7 @@ function fromString(string, encoding) {
300298
} else {
301299
length = byteLength(string, encoding, true);
302300
if (length === -1)
303-
throw new TypeError('"encoding" must be a valid string encoding');
301+
throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding);
304302
if (string.length === 0)
305303
return new FastBuffer();
306304
}
@@ -343,7 +341,7 @@ function fromArrayBuffer(obj, byteOffset, length) {
343341
const maxLength = obj.byteLength - byteOffset;
344342

345343
if (maxLength < 0)
346-
throw new RangeError("'offset' is out of bounds");
344+
throw new errors.RangeError('ERR_BUFFER_OUT_OF_BOUNDS', 'offset');
347345

348346
if (length === undefined) {
349347
length = maxLength;
@@ -355,7 +353,7 @@ function fromArrayBuffer(obj, byteOffset, length) {
355353
length = 0;
356354
} else if (length > 0) {
357355
if (length > maxLength)
358-
throw new RangeError("'length' is out of bounds");
356+
throw new errors.RangeError('ERR_BUFFER_OUT_OF_BOUNDS', 'length');
359357
} else {
360358
length = 0;
361359
}
@@ -399,7 +397,8 @@ Buffer.isBuffer = function isBuffer(b) {
399397

400398
Buffer.compare = function compare(a, b) {
401399
if (!isUint8Array(a) || !isUint8Array(b)) {
402-
throw new TypeError('Arguments must be Buffers or Uint8Arrays');
400+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', ['buf1', 'buf2'],
401+
['buffer', 'uint8Array']);
403402
}
404403

405404
if (a === b) {
@@ -416,13 +415,13 @@ Buffer.isEncoding = function(encoding) {
416415
};
417416
Buffer[internalUtil.kIsEncodingSymbol] = Buffer.isEncoding;
418417

419-
const kConcatErrMsg = '"list" argument must be an Array ' +
420-
'of Buffer or Uint8Array instances';
418+
const kConcatErr = new errors.TypeError('ERR_INVALID_ARG_TYPE', 'list',
419+
['array', 'buffer', 'uint8Array']);
421420

422421
Buffer.concat = function(list, length) {
423422
var i;
424423
if (!Array.isArray(list))
425-
throw new TypeError(kConcatErrMsg);
424+
throw kConcatErr;
426425

427426
if (list.length === 0)
428427
return new FastBuffer();
@@ -440,7 +439,7 @@ Buffer.concat = function(list, length) {
440439
for (i = 0; i < list.length; i++) {
441440
var buf = list[i];
442441
if (!isUint8Array(buf))
443-
throw new TypeError(kConcatErrMsg);
442+
throw kConcatErr;
444443
binding.copy(buf, buffer, pos);
445444
pos += buf.length;
446445
}
@@ -475,7 +474,8 @@ function byteLength(string, encoding) {
475474
return string.byteLength;
476475
}
477476

478-
throw new TypeError('"string" must be a string, Buffer, or ArrayBuffer');
477+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'string',
478+
['string', 'buffer', 'arrayBuffer']);
479479
}
480480

481481
const len = string.length;
@@ -591,7 +591,7 @@ function stringSlice(buf, encoding, start, end) {
591591
return buf.ucs2Slice(start, end);
592592
break;
593593
}
594-
throw new TypeError('Unknown encoding: ' + encoding);
594+
throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding);
595595
}
596596

597597

@@ -633,8 +633,8 @@ Buffer.prototype.toString = function(encoding, start, end) {
633633

634634
Buffer.prototype.equals = function equals(b) {
635635
if (!isUint8Array(b))
636-
throw new TypeError('Argument must be a Buffer or Uint8Array');
637-
636+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'otherBuffer',
637+
['buffer', 'uint8Array']);
638638
if (this === b)
639639
return true;
640640

@@ -659,7 +659,8 @@ Buffer.prototype.compare = function compare(target,
659659
thisStart,
660660
thisEnd) {
661661
if (!isUint8Array(target))
662-
throw new TypeError('Argument must be a Buffer or Uint8Array');
662+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'target',
663+
['buffer', 'uint8Array']);
663664
if (arguments.length === 1)
664665
return compare_(this, target);
665666

@@ -738,8 +739,8 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
738739
return binding.indexOfNumber(buffer, val, byteOffset, dir);
739740
}
740741

741-
throw new TypeError('"val" argument must be string, number, Buffer ' +
742-
'or Uint8Array');
742+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'val',
743+
['string', 'buffer', 'uint8Array']);
743744
}
744745

745746

@@ -765,7 +766,7 @@ function slowIndexOf(buffer, val, byteOffset, encoding, dir) {
765766

766767
default:
767768
if (loweredCase) {
768-
throw new TypeError('Unknown encoding: ' + encoding);
769+
throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding);
769770
}
770771

771772
encoding = ('' + encoding).toLowerCase();
@@ -807,11 +808,11 @@ Buffer.prototype.fill = function fill(val, start, end, encoding) {
807808
}
808809

809810
if (encoding !== undefined && typeof encoding !== 'string') {
810-
throw new TypeError('encoding must be a string');
811+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'encoding', 'string');
811812
}
812813
var normalizedEncoding = internalUtil.normalizeEncoding(encoding);
813814
if (normalizedEncoding === undefined) {
814-
throw new TypeError('Unknown encoding: ' + encoding);
815+
throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding);
815816
}
816817

817818
if (val.length === 0) {
@@ -872,13 +873,13 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
872873
length = remaining;
873874

874875
if (string.length > 0 && (length < 0 || offset < 0))
875-
throw new RangeError('Attempt to write outside buffer bounds');
876+
throw new errors.RangeError('ERR_BUFFER_OUT_OF_BOUNDS', 'length', true);
876877
} else {
877878
// if someone is still calling the obsolete form of write(), tell them.
878879
// we don't want eg buf.write("foo", "utf8", 10) to silently turn into
879880
// buf.write("foo", "utf8"), so we can't ignore extra args
880-
throw new Error('Buffer.write(string, encoding, offset[, length]) ' +
881-
'is no longer supported');
881+
throw new errors.Error('ERR_NO_LONGER_SUPPORTED',
882+
'Buffer.write(string, encoding, offset[, length])');
882883
}
883884

884885
if (!encoding) return this.utf8Write(string, offset, length);
@@ -925,7 +926,7 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
925926
return this.hexWrite(string, offset, length);
926927
break;
927928
}
928-
throw new TypeError('Unknown encoding: ' + encoding);
929+
throw new errors.TypeError('ERR_UNKNOWN_ENCODING', encoding);
929930
};
930931

931932

@@ -1176,7 +1177,7 @@ Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) {
11761177

11771178
function checkInt(buffer, value, offset, ext, max, min) {
11781179
if (value > max || value < min)
1179-
throw new TypeError('"value" argument is out of bounds');
1180+
throw new errors.RangeError('ERR_INVALID_OPT_VALUE', 'value', value);
11801181
if (offset + ext > buffer.length)
11811182
throw new errors.RangeError('ERR_INDEX_OUT_OF_RANGE');
11821183
}
@@ -1448,7 +1449,7 @@ Buffer.prototype.swap16 = function swap16() {
14481449
// dropping down to the native code is faster.
14491450
const len = this.length;
14501451
if (len % 2 !== 0)
1451-
throw new RangeError('Buffer size must be a multiple of 16-bits');
1452+
throw new errors.RangeError('ERR_INVALID_BUFFER_SIZE', '16-bits');
14521453
if (len < 128) {
14531454
for (var i = 0; i < len; i += 2)
14541455
swap(this, i, i + 1);
@@ -1464,7 +1465,7 @@ Buffer.prototype.swap32 = function swap32() {
14641465
// dropping down to the native code is faster.
14651466
const len = this.length;
14661467
if (len % 4 !== 0)
1467-
throw new RangeError('Buffer size must be a multiple of 32-bits');
1468+
throw new errors.RangeError('ERR_INVALID_BUFFER_SIZE', '32-bits');
14681469
if (len < 192) {
14691470
for (var i = 0; i < len; i += 4) {
14701471
swap(this, i, i + 3);
@@ -1482,7 +1483,7 @@ Buffer.prototype.swap64 = function swap64() {
14821483
// dropping down to the native code is faster.
14831484
const len = this.length;
14841485
if (len % 8 !== 0)
1485-
throw new RangeError('Buffer size must be a multiple of 64-bits');
1486+
throw new errors.RangeError('ERR_INVALID_BUFFER_SIZE', '64-bits');
14861487
if (len < 192) {
14871488
for (var i = 0; i < len; i += 8) {
14881489
swap(this, i, i + 7);

lib/internal/errors.js

+35-2
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,11 @@ module.exports = exports = {
109109
// Note: Please try to keep these in alphabetical order
110110
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable');
111111
E('ERR_ASSERTION', '%s');
112+
E('ERR_BUFFER_OUT_OF_BOUNDS', bufferOutOfBounds);
112113
E('ERR_CONSOLE_WRITABLE_STREAM',
113114
'Console expects a writable stream instance for %s');
114115
E('ERR_CPU_USAGE', 'Unable to obtain cpu usage %s');
116+
E('ERR_NO_LONGER_SUPPORTED', '%s is no longer supported');
115117
E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
116118
E('ERR_HTTP_HEADERS_SENT',
117119
'Cannot render headers after they are sent to the client');
@@ -127,6 +129,7 @@ E('ERR_INVALID_ARRAY_LENGTH',
127129
return `The "${name}" array must have a length of ${
128130
length}. Received length ${actual}`;
129131
});
132+
E('ERR_INVALID_BUFFER_SIZE', 'Buffer size must be a multiple of %s');
130133
E('ERR_INVALID_CALLBACK', 'Callback must be a function');
131134
E('ERR_INVALID_CHAR', 'Invalid character in %s');
132135
E('ERR_INVALID_CURSOR_POS',
@@ -173,6 +176,7 @@ E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
173176
'Calling transform done when still transforming');
174177
E('ERR_TRANSFORM_WITH_LENGTH_0',
175178
'Calling transform done when writableState.length != 0');
179+
E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s');
176180
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s');
177181
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
178182
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type');
@@ -183,8 +187,29 @@ E('ERR_V8BREAKITERATOR', 'Full ICU data not installed. ' +
183187
function invalidArgType(name, expected, actual) {
184188
const assert = lazyAssert();
185189
assert(name, 'name is required');
186-
const type = name.includes('.') ? 'property' : 'argument';
187-
var msg = `The "${name}" ${type} must be ${oneOf(expected, 'type')}`;
190+
191+
// determiner: 'must be' or 'must not be'
192+
let determiner;
193+
if (expected.includes('not ')) {
194+
determiner = 'must not be';
195+
expected = expected.split('not ')[1];
196+
} else {
197+
determiner = 'must be';
198+
}
199+
200+
let msg;
201+
if (Array.isArray(name)) {
202+
var names = name.map((val) => `"${val}"`).join(', ');
203+
msg = `The ${names} arguments ${determiner} ${oneOf(expected, 'type')}`;
204+
} else if (name.includes(' argument')) {
205+
// for the case like 'first argument'
206+
msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`;
207+
} else {
208+
const type = name.includes('.') ? 'property' : 'argument';
209+
msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`;
210+
}
211+
212+
// if actual value received, output it
188213
if (arguments.length >= 3) {
189214
msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
190215
}
@@ -231,3 +256,11 @@ function oneOf(expected, thing) {
231256
return `of ${thing} ${String(expected)}`;
232257
}
233258
}
259+
260+
function bufferOutOfBounds(name, isWriting) {
261+
if (isWriting) {
262+
return 'Attempt to write outside buffer bounds';
263+
} else {
264+
return `"${name}" is outside of buffer bounds`;
265+
}
266+
}

0 commit comments

Comments
 (0)