Skip to content
File

Blob: src/node/internal/internal_errors.ts

typescript1001 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4//
5// Adapted from Deno and Node.js:
6// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
7//
8// Adapted from Node.js. Copyright Joyent, Inc. and other Node contributors.
9//
10// Permission is hereby granted, free of charge, to any person obtaining a
11// copy of this software and associated documentation files (the
12// "Software"), to deal in the Software without restriction, including
13// without limitation the rights to use, copy, modify, merge, publish,
14// distribute, sublicense, and/or sell copies of the Software, and to permit
15// persons to whom the Software is furnished to do so, subject to the
16// following conditions:
17//
18// The above copyright notice and this permission notice shall be included
19// in all copies or substantial portions of the Software.
20//
21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
24// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
27// USE OR OTHER DEALINGS IN THE SOFTWARE.
28 
29import { inspect } from 'node-internal:internal_inspect';
30import type { PeerCertificate } from 'node:tls';
31 
32const classRegExp = /^([A-Z][a-z0-9]*)+$/;
33 
34const kTypes = [
35 'string',
36 'function',
37 'number',
38 'object',
39 'Function',
40 'Object',
41 'boolean',
42 'bigint',
43 'symbol',
44];
45 
46export class NodeErrorAbstraction extends Error {
47 code: string;
48 
49 constructor(name: string, code: string, message: string) {
50 super(message);
51 this.code = code;
52 this.name = name;
53 }
54 
55 override toString(): string {
56 return `${this.name} [${this.code}]: ${this.message}`;
57 }
58}
59 
60export class NodeError extends NodeErrorAbstraction {
61 constructor(code: string, message: string) {
62 super(Error.prototype.name, code, message);
63 }
64}
65 
66export class NodeRangeError extends NodeErrorAbstraction {
67 constructor(code: string, message: string) {
68 super(RangeError.prototype.name, code, message);
69 Object.setPrototypeOf(this, RangeError.prototype);
70 this.toString = function (): string {
71 return `${this.name} [${this.code}]: ${this.message}`;
72 };
73 }
74}
75 
76export class NodeTypeError extends NodeErrorAbstraction implements TypeError {
77 constructor(code: string, message: string) {
78 super(TypeError.prototype.name, code, message);
79 Object.setPrototypeOf(this, TypeError.prototype);
80 this.toString = function (): string {
81 return `${this.name} [${this.code}]: ${this.message}`;
82 };
83 }
84}
85 
86export class NodeSyntaxError
87 extends NodeErrorAbstraction
88 implements SyntaxError
89{
90 constructor(code: string, message: string) {
91 super(SyntaxError.prototype.name, code, message);
92 Object.setPrototypeOf(this, SyntaxError.prototype);
93 this.toString = function (): string {
94 return `${this.name} [${this.code}]: ${this.message}`;
95 };
96 }
97}
98 
99function createInvalidArgType(
100 name: string,
101 expected: string | string[]
102): string {
103 // https://github.com/nodejs/node/blob/f3eb224/lib/internal/errors.js#L1037-L1087
104 expected = Array.isArray(expected) ? expected : [expected];
105 let msg = 'The ';
106 if (name.endsWith(' argument')) {
107 // For cases like 'first argument'
108 msg += `${name} `;
109 } else {
110 const type = name.includes('.') ? 'property' : 'argument';
111 msg += `"${name}" ${type} `;
112 }
113 msg += 'must be ';
114 
115 const types = [];
116 const instances = [];
117 const other = [];
118 for (const value of expected) {
119 if (kTypes.includes(value)) {
120 types.push(value.toLocaleLowerCase());
121 } else if (classRegExp.test(value)) {
122 instances.push(value);
123 } else {
124 other.push(value);
125 }
126 }
127 
128 // Special handle `object` in case other instances are allowed to outline
129 // the differences between each other.
130 if (instances.length > 0) {
131 const pos = types.indexOf('object');
132 if (pos !== -1) {
133 types.splice(pos, 1);
134 instances.push('Object');
135 }
136 }
137 
138 if (types.length > 0) {
139 if (types.length > 2) {
140 const last = types.pop();
141 msg += `one of type ${types.join(', ')}, or ${last}`;
142 } else if (types.length === 2) {
143 msg += `one of type ${types[0]} or ${types[1]}`;
144 } else {
145 msg += `of type ${types[0]}`;
146 }
147 if (instances.length > 0 || other.length > 0) {
148 msg += ' or ';
149 }
150 }
151 
152 if (instances.length > 0) {
153 if (instances.length > 2) {
154 const last = instances.pop();
155 msg += `an instance of ${instances.join(', ')}, or ${last}`;
156 } else {
157 msg += `an instance of ${instances[0]}`;
158 if (instances.length === 2) {
159 msg += ` or ${instances[1]}`;
160 }
161 }
162 if (other.length > 0) {
163 msg += ' or ';
164 }
165 }
166 
167 if (other.length > 0) {
168 if (other.length > 2) {
169 const last = other.pop();
170 msg += `one of ${other.join(', ')}, or ${last}`;
171 } else if (other.length === 2) {
172 msg += `one of ${other[0]} or ${other[1]}`;
173 } else {
174 if (other[0]?.toLowerCase() !== other[0]) {
175 msg += 'an ';
176 }
177 msg += `${other[0]}`;
178 }
179 }
180 
181 return msg;
182}
183 
184function invalidArgTypeHelper(input: unknown): string {
185 if (input == null) {
186 return ` Received ${input}`;
187 }
188 if (typeof input === 'function' && input.name) {
189 return ` Received function ${input.name}`;
190 }
191 if (typeof input === 'object') {
192 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
193 if (input.constructor?.name) {
194 return ` Received an instance of ${input.constructor.name}`;
195 }
196 return ` Received ${inspect(input, { depth: -1 })}`;
197 }
198 let inspected = inspect(input, { colors: false });
199 if (inspected.length > 25) {
200 inspected = `${inspected.slice(0, 25)}...`;
201 }
202 return ` Received type ${typeof input} (${inspected})`;
203}
204 
205function addNumericalSeparator(val: string): string {
206 let res = '';
207 let i = val.length;
208 const start = val[0] === '-' ? 1 : 0;
209 for (; i >= start + 4; i -= 3) {
210 res = `_${val.slice(i - 3, i)}${res}`;
211 }
212 return `${val.slice(0, i)}${res}`;
213}
214 
215export class ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY extends NodeError {
216 constructor() {
217 super(
218 'ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY',
219 'Public key is not valid for specified curve'
220 );
221 }
222}
223 
224export class ERR_CRYPTO_HASH_FINALIZED extends NodeError {
225 constructor() {
226 super('ERR_CRYPTO_HASH_FINALIZED', 'Digest already called');
227 }
228}
229 
230export class ERR_CRYPTO_HASH_UPDATE_FAILED extends NodeError {
231 constructor() {
232 super('ERR_CRYPTO_HASH_UPDATE_FAILED', 'Hash update failed');
233 }
234}
235 
236export class ERR_CRYPTO_INCOMPATIBLE_KEY extends NodeError {
237 constructor(name: string, msg: string) {
238 super('ERR_CRYPTO_INCOMPATIBLE_KEY', `Incompatible ${name}: ${msg}`);
239 }
240}
241 
242export class ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE extends NodeError {
243 constructor(actual: string, expected: string) {
244 super(
245 'ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE',
246 `Invalid key object type ${actual}, expected ${expected}.`
247 );
248 }
249}
250 
251export class ERR_INVALID_ARG_TYPE_RANGE extends NodeRangeError {
252 constructor(name: string, expected: string | string[], actual: unknown) {
253 const msg = createInvalidArgType(name, expected);
254 
255 super('ERR_INVALID_ARG_TYPE', `${msg}.${invalidArgTypeHelper(actual)}`);
256 }
257}
258 
259export class ERR_INVALID_ARG_TYPE extends NodeTypeError {
260 constructor(name: string, expected: string | string[], actual: unknown) {
261 const msg = createInvalidArgType(name, expected);
262 
263 super('ERR_INVALID_ARG_TYPE', `${msg}.${invalidArgTypeHelper(actual)}`);
264 }
265 
266 static RangeError = ERR_INVALID_ARG_TYPE_RANGE;
267}
268 
269export class ERR_INVALID_ARG_VALUE_RANGE extends NodeRangeError {
270 constructor(name: string, value: unknown, reason: string = 'is invalid') {
271 const type = name.includes('.') ? 'property' : 'argument';
272 const inspected = inspect(value);
273 
274 super(
275 'ERR_INVALID_ARG_VALUE',
276 `The ${type} '${name}' ${reason}. Received ${inspected}`
277 );
278 }
279}
280 
281export class ERR_INVALID_ARG_VALUE extends NodeTypeError {
282 constructor(name: string, value: unknown, reason: string = 'is invalid') {
283 const type = name.includes('.') ? 'property' : 'argument';
284 const inspected = inspect(value);
285 
286 super(
287 'ERR_INVALID_ARG_VALUE',
288 `The ${type} '${name}' ${reason}. Received ${inspected}`
289 );
290 }
291 
292 static RangeError = ERR_INVALID_ARG_VALUE_RANGE;
293}
294 
295export class ERR_OUT_OF_RANGE extends RangeError {
296 code = 'ERR_OUT_OF_RANGE';
297 
298 constructor(
299 str: string,
300 range: string,
301 input: unknown,
302 replaceDefaultBoolean = false
303 ) {
304 // TODO(later): Implement internal assert?
305 // assert(range, 'Missing "range" argument');
306 let msg = replaceDefaultBoolean
307 ? str
308 : `The value of "${str}" is out of range.`;
309 let received;
310 if (Number.isInteger(input) && Math.abs(input as number) > 2 ** 32) {
311 received = addNumericalSeparator(String(input));
312 } else if (typeof input === 'bigint') {
313 received = String(input);
314 if (input > 2n ** 32n || input < -(2n ** 32n)) {
315 received = addNumericalSeparator(received);
316 }
317 received += 'n';
318 } else {
319 received = inspect(input);
320 }
321 msg += ` It must be ${range}. Received ${received}`;
322 
323 super(msg);
324 
325 const { name } = this;
326 // Add the error code to the name to include it in the stack trace.
327 this.name = `${name} [${this.code}]`;
328 // Access the stack to generate the error message including the error code from the name.
329 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
330 this.stack;
331 // Reset the name to the actual name.
332 this.name = name;
333 }
334}
335 
336export class ERR_UNHANDLED_ERROR extends NodeError {
337 constructor(x: string) {
338 super('ERR_UNHANDLED_ERROR', `Unhandled error. (${x})`);
339 }
340}
341 
342export class ERR_INVALID_THIS extends NodeTypeError {
343 constructor(x: string) {
344 super('ERR_INVALID_THIS', `Value of "this" must be of type ${x}`);
345 }
346}
347 
348export class ERR_BUFFER_OUT_OF_BOUNDS extends NodeRangeError {
349 constructor(name?: string) {
350 super(
351 'ERR_BUFFER_OUT_OF_BOUNDS',
352 name
353 ? `"${name}" is outside of buffer bounds`
354 : 'Attempt to access memory outside buffer bounds'
355 );
356 }
357}
358 
359export class ERR_INVALID_BUFFER_SIZE extends NodeRangeError {
360 constructor(size: number) {
361 super(
362 'ERR_INVALID_BUFFER_SIZE',
363 `Buffer size must be a multiple of ${size}-bits`
364 );
365 }
366}
367 
368export class ERR_UNKNOWN_ENCODING extends NodeTypeError {
369 constructor(x: string) {
370 super('ERR_UNKNOWN_ENCODING', `Unknown encoding: ${x}`);
371 }
372}
373 
374export class ERR_STREAM_PREMATURE_CLOSE extends NodeTypeError {
375 constructor() {
376 super('ERR_STREAM_PREMATURE_CLOSE', 'Premature close');
377 }
378}
379 
380export class AbortError extends Error {
381 code: string;
382 
383 constructor(message = 'The operation was aborted', options?: ErrorOptions) {
384 if (options !== undefined && typeof options !== 'object') {
385 throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
386 }
387 super(message, options);
388 this.code = 'ABORT_ERR';
389 this.name = 'AbortError';
390 }
391}
392 
393function determineSpecificType(value: unknown): string {
394 if (value == null) {
395 // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
396 return '' + value;
397 }
398 if (typeof value === 'function' && value.name) {
399 return `function ${value.name}`;
400 }
401 if (typeof value === 'object') {
402 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
403 if (value.constructor?.name) {
404 return `an instance of ${value.constructor.name}`;
405 }
406 return inspect(value, { depth: -1 });
407 }
408 let inspected = inspect(value, { colors: false });
409 if (inspected.length > 28) inspected = `${inspected.slice(0, 25)}...`;
410 
411 return `type ${typeof value} (${inspected})`;
412}
413 
414export class ERR_AMBIGUOUS_ARGUMENT extends NodeTypeError {
415 constructor(x: string, y: string) {
416 super('ERR_AMBIGUOUS_ARGUMENT', `The "${x}" argument is ambiguous. ${y}`);
417 }
418}
419 
420export class ERR_INVALID_RETURN_VALUE extends NodeTypeError {
421 constructor(input: string, name: string, value: unknown) {
422 super(
423 'ERR_INVALID_RETURN_VALUE',
424 `Expected ${input} to be returned from the "${name}" function but got ${determineSpecificType(
425 value
426 )}.`
427 );
428 }
429}
430 
431export class ERR_MULTIPLE_CALLBACK extends NodeError {
432 constructor() {
433 super('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times');
434 }
435}
436 
437export class ERR_MISSING_ARGS extends NodeTypeError {
438 constructor(...args: (string | string[])[]) {
439 let msg = 'The ';
440 
441 const len = args.length;
442 
443 const wrap = (a: unknown): string => `"${a}"`;
444 
445 args = args.map((a) =>
446 Array.isArray(a) ? a.map(wrap).join(' or ') : wrap(a)
447 );
448 
449 switch (len) {
450 case 1:
451 msg += `${args[0]} argument`;
452 break;
453 case 2:
454 msg += `${args[0]} and ${args[1]} arguments`;
455 break;
456 default:
457 msg += args.slice(0, len - 1).join(', ');
458 msg += `, and ${args[len - 1]} arguments`;
459 break;
460 }
461 
462 super('ERR_MISSING_ARGS', `${msg} must be specified`);
463 }
464}
465 
466// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents,@typescript-eslint/no-duplicate-type-constituents
467export type Falsy = false | 0 | -0 | 0n | '' | null | undefined | typeof NaN;
468export class ERR_FALSY_VALUE_REJECTION extends NodeError {
469 reason: Falsy;
470 constructor(reason: Falsy) {
471 super('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
472 this.reason = reason;
473 }
474}
475 
476export class ERR_METHOD_NOT_IMPLEMENTED extends NodeError {
477 constructor(name: string | symbol) {
478 if (typeof name === 'symbol') {
479 name = name.description as string;
480 }
481 super(
482 'ERR_METHOD_NOT_IMPLEMENTED',
483 `The ${name} method is not implemented`
484 );
485 }
486}
487 
488export class ERR_STREAM_CANNOT_PIPE extends NodeError {
489 constructor() {
490 super('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable');
491 }
492}
493export class ERR_STREAM_DESTROYED extends NodeError {
494 constructor(name: string | symbol) {
495 if (typeof name === 'symbol') {
496 name = name.description as string;
497 }
498 super(
499 'ERR_STREAM_DESTROYED',
500 `Cannot call ${name} after a stream was destroyed`
501 );
502 }
503}
504export class ERR_STREAM_ALREADY_FINISHED extends NodeError {
505 constructor(name: string | symbol) {
506 if (typeof name === 'symbol') {
507 name = name.description as string;
508 }
509 super(
510 'ERR_STREAM_ALREADY_FINISHED',
511 `Cannot call ${name} after a stream was finished`
512 );
513 }
514}
515export class ERR_STREAM_NULL_VALUES extends NodeTypeError {
516 constructor() {
517 super('ERR_STREAM_NULL_VALUES', 'May not write null values to stream');
518 }
519}
520export class ERR_STREAM_WRITE_AFTER_END extends NodeError {
521 constructor() {
522 super('ERR_STREAM_WRITE_AFTER_END', 'write after end');
523 }
524}
525 
526export class ERR_STREAM_PUSH_AFTER_EOF extends NodeError {
527 constructor() {
528 super('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF');
529 }
530}
531 
532export class ERR_STREAM_UNSHIFT_AFTER_END_EVENT extends NodeError {
533 constructor() {
534 super(
535 'ERR_STREAM_UNSHIFT_AFTER_END_EVENT',
536 'stream.unshift() after end event'
537 );
538 }
539}
540 
541export class ERR_BUFFER_TOO_LARGE extends NodeRangeError {
542 constructor(value: number) {
543 super(
544 'ERR_BUFFER_TOO_LARGE',
545 `Cannot create a Buffer larger than ${value} bytes`
546 );
547 }
548}
549 
550export class ERR_BROTLI_INVALID_PARAM extends NodeRangeError {
551 constructor(value: unknown) {
552 super(
553 'ERR_BROTLI_INVALID_PARAM',
554 `${value} is not a valid Brotli parameter`
555 );
556 }
557}
558 
559export class ERR_ZSTD_INVALID_PARAM extends NodeRangeError {
560 constructor(value: unknown) {
561 super('ERR_ZSTD_INVALID_PARAM', `${value} is not a valid Zstd parameter`);
562 }
563}
564 
565export class ERR_ZLIB_INITIALIZATION_FAILED extends NodeError {
566 constructor() {
567 super('ERR_ZLIB_INITIALIZATION_FAILED', 'Initialization failed');
568 }
569}
570 
571export class ERR_INVALID_URL extends NodeError {
572 input: string;
573 
574 constructor(url: string) {
575 super('ERR_INVALID_URL', 'Invalid URL');
576 this.input = url;
577 }
578}
579 
580export class ERR_INVALID_URL_SCHEME extends NodeError {
581 constructor(scheme: string) {
582 super('ERR_INVALID_URL_SCHEME', `The URL must be of scheme ${scheme}`);
583 }
584}
585 
586export class ERR_INVALID_FILE_URL_HOST extends NodeError {
587 constructor(input: string) {
588 super(
589 'ERR_INVALID_FILE_URL_HOST',
590 `File URL host must be "localhost" or empty on ${input}`
591 );
592 }
593}
594 
595export class ERR_INVALID_FILE_URL_PATH extends NodeError {
596 constructor(input: string) {
597 super('ERR_INVALID_FILE_URL_PATH', `File URL path ${input}`);
598 }
599}
600 
601export class ERR_INVALID_URI extends NodeError {
602 constructor() {
603 super('ERR_INVALID_URI', 'URI malformed');
604 this.name = 'URIError';
605 }
606}
607 
608// Example:
609//
610// Error: queryTxt ENOTFOUND google.com2
611// at QueryReqWrap.onresolve [as oncomplete] (node:internal/dns/callback_resolver:45:19)
612// at QueryReqWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
613// errno: undefined,
614// code: 'ENOTFOUND',
615// syscall: 'queryTxt',
616// hostname: 'google.com2'
617// }
618export class DnsError extends NodeError {
619 errno = undefined;
620 hostname: string;
621 syscall: string;
622 
623 constructor(hostname: string, code: string, syscall: string) {
624 super(code, `${syscall} ${code} ${hostname}`);
625 this.hostname = hostname;
626 this.syscall = syscall;
627 }
628}
629 
630export class ERR_OPTION_NOT_IMPLEMENTED extends NodeError {
631 constructor(name: string | symbol) {
632 if (typeof name === 'symbol') {
633 name = name.description as string;
634 }
635 super(
636 'ERR_OPTION_NOT_IMPLEMENTED',
637 `The ${name} option is not implemented`
638 );
639 }
640}
641 
642export class ERR_SOCKET_BAD_PORT extends NodeError {
643 constructor(name: string, port: unknown, allowZero: boolean) {
644 const operator = allowZero ? '>=' : '>';
645 super(
646 'ERR_SOCKET_BAD_PORT',
647 `${name} should be ${operator} 0 and < 65536. Received ${typeof port}.`
648 );
649 }
650}
651 
652export class EPIPE extends NodeError {
653 constructor() {
654 super('EPIPE', 'This socket has been ended by the other party');
655 }
656}
657 
658export class ERR_SOCKET_CLOSED_BEFORE_CONNECTION extends NodeError {
659 constructor() {
660 super(
661 'ERR_SOCKET_CLOSED_BEFORE_CONNECTION',
662 'Socket closed before connection established'
663 );
664 }
665}
666 
667export class ERR_SOCKET_CLOSED extends NodeError {
668 constructor() {
669 super('ERR_SOCKET_CLOSED', 'Socket is closed');
670 }
671}
672 
673export class ERR_SOCKET_CONNECTING extends NodeError {
674 constructor() {
675 super('ERR_SOCKET_CONNECTING', 'Socket is already connecting');
676 }
677}
678 
679export class ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS extends NodeError {
680 constructor(arg0: string, arg1: string) {
681 super(
682 'ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS',
683 `The selected key encoding ${arg0} ${arg1}.`
684 );
685 }
686}
687 
688export class ERR_CRYPTO_INVALID_JWK extends NodeTypeError {
689 constructor() {
690 super('ERR_CRYPTO_INVALID_JWK', 'Invalid JWK data');
691 }
692}
693 
694export class ERR_INCOMPATIBLE_OPTION_PAIR extends NodeError {
695 constructor(a: string, b: string) {
696 super(
697 'ERR_INCOMPATIBLE_OPTION_PAIR',
698 `The options "${a}" and "${b}" are mutually exclusive.`
699 );
700 }
701}
702 
703export class ERR_MISSING_OPTION extends NodeError {
704 constructor(name: string) {
705 super('ERR_MISSING_OPTION', name);
706 }
707}
708 
709export class ERR_UNSUPPORTED_OPERATION extends NodeError {
710 constructor() {
711 super(
712 'ERR_UNSUPPORTED_OPERATION',
713 'The requested operation is unsupported'
714 );
715 }
716}
717 
718export class ERR_CRYPTO_SIGN_KEY_REQUIRED extends NodeError {
719 constructor() {
720 super('ERR_CRYPTO_SIGN_KEY_REQUIRED', 'No key provided to sign');
721 }
722}
723 
724export class ERR_TLS_HANDSHAKE_TIMEOUT extends NodeError {
725 constructor() {
726 super('ERR_TLS_HANDSHAKE_TIMEOUT', 'TLS handshake timeout');
727 }
728}
729 
730export class ERR_TLS_INVALID_CONTEXT extends NodeTypeError {
731 constructor(field: string) {
732 super('ERR_TLS_INVALID_CONTEXT', `${field} must be a SecureContext`);
733 }
734}
735 
736export class ERR_TLS_CERT_ALTNAME_INVALID extends NodeError {
737 reason: string;
738 host: string;
739 cert?: Partial<PeerCertificate> | undefined;
740 
741 constructor(reason: string, host: string, cert?: Partial<PeerCertificate>) {
742 super('ERR_TLS_CERT_ALTNAME_INVALID', reason);
743 this.reason = reason;
744 this.host = host;
745 this.cert = cert;
746 }
747}
748 
749export class ERR_TLS_CERT_ALTNAME_FORMAT extends NodeSyntaxError {
750 constructor() {
751 super(
752 'ERR_TLS_CERT_ALTNAME_FORMAT',
753 'Invalid subject alternative name string'
754 );
755 }
756}
757 
758export class ConnResetException extends NodeError {
759 path?: string | undefined;
760 host?: string | undefined;
761 port?: number | undefined;
762 localAddress?: string | undefined;
763 
764 constructor(message: string) {
765 super('ECONNRESET', message);
766 }
767}
768 
769export function aggregateTwoErrors(
770 innerError: unknown,
771 outerError: Error | null | undefined
772): AggregateError {
773 if (innerError && outerError && innerError !== outerError) {
774 if ('errors' in outerError && Array.isArray(outerError.errors)) {
775 // If `outerError` is already an `AggregateError`.
776 outerError.errors.push(innerError);
777 return outerError as AggregateError;
778 }
779 const err = new AggregateError(
780 [outerError, innerError],
781 outerError.message
782 );
783 (err as unknown as NodeError).code = (outerError as NodeError).code;
784 return err;
785 }
786 return (innerError || outerError) as AggregateError;
787}
788 
789export class ERR_INVALID_IP_ADDRESS extends NodeTypeError {
790 constructor(ipAddress: string) {
791 super('ERR_INVALID_IP_ADDRESS', `Invalid IP address: ${ipAddress}`);
792 }
793}
794 
795export class ERR_INVALID_ADDRESS extends NodeTypeError {
796 constructor() {
797 super('ERR_INVALID_ADDRESS', 'Invalid socket address');
798 }
799}
800 
801export class ERR_STREAM_WRAP extends NodeError {
802 constructor() {
803 super(
804 'ERR_STREAM_WRAP',
805 'Stream has StringDecoder set or is in objectMode'
806 );
807 }
808}
809 
810export class ERR_INVALID_HTTP_TOKEN extends NodeTypeError {
811 constructor(label: string, name: string | undefined) {
812 super(
813 'ERR_INVALID_HTTP_TOKEN',
814 `${label} must be a valid HTTP token ["${name}"]`
815 );
816 }
817}
818 
819export class ERR_HTTP_INVALID_HEADER_VALUE extends NodeTypeError {
820 constructor(value: string | undefined, header: string | undefined) {
821 super(
822 'ERR_HTTP_INVALID_HEADER_VALUE',
823 `Invalid value "${value}" for header "${header}"`
824 );
825 }
826}
827 
828export class ERR_INVALID_CHAR extends NodeTypeError {
829 constructor(name: string, field?: string) {
830 let msg = `Invalid character in ${name}`;
831 if (field !== undefined) {
832 msg += ` ["${field}"]`;
833 }
834 super('ERR_INVALID_CHAR', msg);
835 }
836}
837 
838export class NodeSyscallError extends NodeError {
839 syscall: string;
840 errno?: number;
841 constructor(code: string, message: string, syscall: string) {
842 super(code, message);
843 this.syscall = syscall;
844 }
845}
846 
847export class ERR_ENOENT extends NodeSyscallError {
848 path: string;
849 constructor(path: string, options: { syscall: string }) {
850 super(
851 'ENOENT',
852 `no such file or directory, ${options.syscall} '${path}'`,
853 options.syscall
854 );
855 this.path = path;
856 this.errno = -2; // ENOENT
857 }
858}
859 
860export class ERR_EBADF extends NodeSyscallError {
861 constructor(options: { syscall: string }) {
862 super('EBADF', 'Bad file descriptor', options.syscall);
863 this.errno = -9; // EBADF
864 }
865}
866 
867export class ERR_EINVAL extends NodeSyscallError {
868 path?: string;
869 constructor(options: { syscall: string; path?: string }) {
870 const message = options.path
871 ? `invalid argument, ${options.syscall} '${options.path}'`
872 : 'invalid argument';
873 super('EINVAL', message, options.syscall);
874 if (options.path !== undefined) {
875 this.path = options.path;
876 }
877 this.errno = -22; // EINVAL
878 }
879}
880 
881export class ERR_EEXIST extends NodeSyscallError {
882 path?: string;
883 constructor(options: { syscall: string; path?: string }) {
884 const message = options.path
885 ? `file already exists, ${options.syscall} '${options.path}'`
886 : 'file already exists';
887 super('EEXIST', message, options.syscall);
888 if (options.path !== undefined) {
889 this.path = options.path;
890 }
891 this.errno = -17; // EEXIST
892 }
893}
894 
895export class ERR_EPERM extends NodeSyscallError {
896 path?: string;
897 constructor(options: { syscall: string; errno?: number; path?: string }) {
898 const message = options.path
899 ? `operation not permitted, ${options.syscall} '${options.path}'`
900 : 'operation not permitted';
901 super('EPERM', message, options.syscall);
902 if (options.path !== undefined) {
903 this.path = options.path;
904 }
905 this.errno = options.errno ?? 1; // EPERM
906 }
907}
908 
909export class ERR_DIR_CLOSED extends NodeError {
910 constructor() {
911 super('ERR_DIR_CLOSED', 'Directory is closed');
912 }
913}
914 
915export class ERR_HTTP_HEADERS_SENT extends NodeError {
916 constructor(action: string) {
917 super(
918 'ERR_HTTP_HEADERS_SENT',
919 `Cannot ${action} headers after they are sent to the client`
920 );
921 }
922}
923 
924export class ERR_HTTP_CONTENT_LENGTH_MISMATCH extends NodeError {
925 constructor(actual: number, expected: number) {
926 super(
927 'ERR_HTTP_CONTENT_LENGTH_MISMATCH',
928 `Request body length does not match content-length header. Expected: ${expected}, Actual: ${actual}`
929 );
930 }
931}
932 
933export class ERR_HTTP_BODY_NOT_ALLOWED extends NodeError {
934 constructor() {
935 super(
936 'ERR_HTTP_BODY_NOT_ALLOWED',
937 'Request with GET/HEAD method cannot have body'
938 );
939 }
940}
941 
942export class ERR_INVALID_PROTOCOL extends NodeTypeError {
943 constructor(actual: string, expected: string) {
944 super(
945 'ERR_INVALID_PROTOCOL',
946 `Protocol "${actual}" not supported. Expected "${expected}"`
947 );
948 }
949}
950 
951export class ERR_UNESCAPED_CHARACTERS extends NodeTypeError {
952 constructor(field: string) {
953 super('ERR_UNESCAPED_CHARACTERS', `${field} contains unescaped characters`);
954 }
955}
956 
957export class ERR_SYSTEM_ERROR extends NodeError {
958 constructor(message: string) {
959 super('ERR_SYSTEM_ERROR', message);
960 }
961}
962 
963export class ERR_HTTP_INVALID_STATUS_CODE extends NodeRangeError {
964 constructor(statusCode: string | number) {
965 super('ERR_HTTP_INVALID_STATUS_CODE', `Invalid status code: ${statusCode}`);
966 }
967}
968 
969export class ERR_SERVER_ALREADY_LISTEN extends NodeError {
970 constructor() {
971 super(
972 'ERR_SERVER_ALREADY_LISTEN',
973 'Listen method has been called more than once without closing.'
974 );
975 }
976}
977 
978export class ERR_ILLEGAL_CONSTRUCTOR extends NodeTypeError {
979 constructor() {
980 super('ERR_ILLEGAL_CONSTRUCTOR', 'Illegal constructor');
981 }
982}
983 
984export class ERR_PERFORMANCE_INVALID_TIMESTAMP extends NodeTypeError {
985 constructor(value: unknown) {
986 super(
987 'ERR_PERFORMANCE_INVALID_TIMESTAMP',
988 `${value} is not a valid timestamp`
989 );
990 }
991}
992 
993export class ERR_TRACE_EVENTS_CATEGORY_REQUIRED extends NodeTypeError {
994 constructor() {
995 super(
996 'ERR_TRACE_EVENTS_CATEGORY_REQUIRED',
997 'At least one category is required'
998 );
999 }
1000}