Skip to content

Commit d457a98

Browse files
committed
url: port WHATWG URL API to internal/errors
Also slightly revises grammar. PR-URL: #12574 Refs: #11273 Refs: #11299 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Daijiro Wachi <[email protected]>
1 parent b7a341d commit d457a98

22 files changed

+374
-113
lines changed

doc/api/errors.md

+81
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,13 @@ found [here][online].
563563
<a id="nodejs-error-codes"></a>
564564
## Node.js Error Codes
565565

566+
<a id="ERR_ARG_NOT_ITERABLE"></a>
567+
### ERR_ARG_NOT_ITERABLE
568+
569+
The `'ERR_ARG_NOT_ITERABLE'` error code is used generically to identify that an
570+
iterable argument (i.e. a value that works with `for...of` loops) is required,
571+
but not provided to a Node.js API.
572+
566573
<a id="ERR_INVALID_ARG_TYPE"></a>
567574
### ERR_INVALID_ARG_TYPE
568575

@@ -575,6 +582,76 @@ an argument of the wrong type has been passed to a Node.js API.
575582
The `'ERR_INVALID_CALLBACK'` error code is used generically to identify that
576583
a callback function is required and has not been provided to a Node.js API.
577584

585+
<a id="ERR_INVALID_FILE_URL_HOST"></a>
586+
### ERR_INVALID_FILE_URL_HOST
587+
588+
An error with the `'ERR_INVALID_FILE_URL_HOST'` code may be thrown when a
589+
Node.js API that consumes `file:` URLs (such as certain functions in the
590+
[`fs`][] module) encounters a file URL with an incompatible host. Currently,
591+
this situation can only occur on Unix-like systems, where only `localhost` or
592+
an empty host is supported.
593+
594+
<a id="ERR_INVALID_FILE_URL_PATH"></a>
595+
### ERR_INVALID_FILE_URL_PATH
596+
597+
An error with the `'ERR_INVALID_FILE_URL_PATH'` code may be thrown when a
598+
Node.js API that consumes `file:` URLs (such as certain functions in the
599+
[`fs`][] module) encounters a file URL with an incompatible path. The exact
600+
semantics for determining whether a path can be used is platform-dependent.
601+
602+
<a id="ERR_INVALID_THIS"></a>
603+
### ERR_INVALID_THIS
604+
605+
The `'ERR_INVALID_THIS'` error code is used generically to identify that a
606+
Node.js API function is called with an incompatible `this` value.
607+
608+
Example:
609+
610+
```js
611+
const { URLSearchParams } = require('url');
612+
const urlSearchParams = new URLSearchParams('foo=bar&baz=new');
613+
614+
const buf = Buffer.alloc(1);
615+
urlSearchParams.has.call(buf, 'foo');
616+
// Throws a TypeError with code 'ERR_INVALID_THIS'
617+
```
618+
619+
<a id="ERR_INVALID_TUPLE"></a>
620+
### ERR_INVALID_TUPLE
621+
622+
An error with code `'ERR_INVALID_TUPLE'` is thrown when an element in the
623+
`iterable` provided to the [WHATWG][WHATWG URL API] [`URLSearchParams`
624+
constructor][`new URLSearchParams(iterable)`] does not represent a `[name,
625+
value]` tuple – that is, if an element is not iterable, or does not consist of
626+
exactly two elements.
627+
628+
<a id="ERR_INVALID_URL"></a>
629+
### ERR_INVALID_URL
630+
631+
An error using the `'ERR_INVALID_URL'` code is thrown when an invalid URL is
632+
passed to the [WHATWG][WHATWG URL API] [`URL` constructor][`new URL(input)`] to
633+
be parsed. The thrown error object typically has an additional property
634+
`'input'` that contains the URL that failed to parse.
635+
636+
<a id="ERR_INVALID_URL_SCHEME"></a>
637+
### ERR_INVALID_URL_SCHEME
638+
639+
The code `'ERR_INVALID_URL_SCHEME'` is used generically to signify an attempt
640+
to use a URL of an incompatible scheme (aka protocol) for a specific purpose.
641+
It is currently only used in the [WHATWG URL API][] support in the [`fs`][]
642+
module (which only accepts URLs with `'file'` scheme), but may be used in other
643+
Node.js APIs as well in the future.
644+
645+
<a id="ERR_MISSING_ARGS"></a>
646+
### ERR_MISSING_ARGS
647+
648+
The `'ERR_MISSING_ARGS'` error code is a generic error code for instances where
649+
a required argument of a Node.js API is not passed. This is currently only used
650+
in the [WHATWG URL API][] for strict compliance with the specification (which
651+
in some cases may accept `func(undefined)` but not `func()`). In most native
652+
Node.js APIs, `func(undefined)` and `func()` are treated identically, and the
653+
[`ERR_INVALID_ARG_TYPE`][] error code may be used instead.
654+
578655
<a id="ERR_STDERR_CLOSE"></a>
579656
### ERR_STDERR_CLOSE
580657

@@ -627,11 +704,15 @@ likely an indication of a bug within Node.js itself.
627704
[`process.on('uncaughtException')`]: process.html#process_event_uncaughtexception
628705
[domains]: domain.html
629706
[event emitter-based]: events.html#events_class_eventemitter
707+
[`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE
630708
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
631709
[Node.js Error Codes]: #nodejs-error-codes
632710
[online]: http://man7.org/linux/man-pages/man3/errno.3.html
633711
[stream-based]: stream.html
634712
[syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html
635713
[try-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
714+
[`new URL(input)`]: url.html#url_constructor_new_url_input_base
715+
[`new URLSearchParams(iterable)`]: url.html#url_constructor_new_urlsearchparams_iterable
636716
[V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API
637717
[vm]: vm.html
718+
[WHATWG URL API]: url.html#url_the_whatwg_url_api

lib/internal/errors.js

+46-10
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,18 @@ module.exports = exports = {
7979
// Any error code added here should also be added to the documentation
8080
//
8181
// Note: Please try to keep these in alphabetical order
82+
E('ERR_ARG_NOT_ITERABLE', '%s must be iterable');
8283
E('ERR_ASSERTION', (msg) => msg);
8384
E('ERR_INVALID_ARG_TYPE', invalidArgType);
8485
E('ERR_INVALID_CALLBACK', 'callback must be a function');
86+
E('ERR_INVALID_FILE_URL_HOST', 'File URL host %s');
87+
E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s');
88+
E('ERR_INVALID_THIS', 'Value of "this" must be of type %s');
89+
E('ERR_INVALID_TUPLE', '%s must be an iterable %s tuple');
90+
E('ERR_INVALID_URL', 'Invalid URL: %s');
91+
E('ERR_INVALID_URL_SCHEME',
92+
(expected) => `The URL must be ${oneOf(expected, 'scheme')}`);
93+
E('ERR_MISSING_ARGS', missingArgs);
8594
E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed');
8695
E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed');
8796
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type');
@@ -91,22 +100,49 @@ E('ERR_UNKNOWN_BUILTIN_MODULE', (id) => `No such built-in module: ${id}`);
91100

92101
function invalidArgType(name, expected, actual) {
93102
assert(name, 'name is required');
103+
var msg = `The "${name}" argument must be ${oneOf(expected, 'type')}`;
104+
if (arguments.length >= 3) {
105+
msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
106+
}
107+
return msg;
108+
}
109+
110+
function missingArgs(...args) {
111+
assert(args.length > 0, 'At least one arg needs to be specified');
112+
let msg = 'The ';
113+
const len = args.length;
114+
args = args.map((a) => `"${a}"`);
115+
switch (len) {
116+
case 1:
117+
msg += `${args[0]} argument`;
118+
break;
119+
case 2:
120+
msg += `${args[0]} and ${args[1]} arguments`;
121+
break;
122+
default:
123+
msg += args.slice(0, len - 1).join(', ');
124+
msg += `, and ${args[len - 1]} arguments`;
125+
break;
126+
}
127+
return `${msg} must be specified`;
128+
}
129+
130+
function oneOf(expected, thing) {
94131
assert(expected, 'expected is required');
95-
var msg = `The "${name}" argument must be `;
132+
assert(typeof thing === 'string', 'thing is required');
96133
if (Array.isArray(expected)) {
97-
var len = expected.length;
134+
const len = expected.length;
135+
assert(len > 0, 'At least one expected value needs to be specified');
98136
expected = expected.map((i) => String(i));
99-
if (len > 1) {
100-
msg += `one of type ${expected.slice(0, len - 1).join(', ')}, or ` +
137+
if (len > 2) {
138+
return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` +
101139
expected[len - 1];
140+
} else if (len === 2) {
141+
return `one of ${thing} ${expected[0]} or ${expected[1]}`;
102142
} else {
103-
msg += `of type ${expected[0]}`;
143+
return `of ${thing} ${expected[0]}`;
104144
}
105145
} else {
106-
msg += `of type ${String(expected)}`;
107-
}
108-
if (arguments.length >= 3) {
109-
msg += `. Received type ${actual !== null ? typeof actual : 'null'}`;
146+
return `of ${thing} ${String(expected)}`;
110147
}
111-
return msg;
112148
}

0 commit comments

Comments
 (0)