Skip to content

Commit 9cb390d

Browse files
starkwangrefack
authored andcommitted
errors: migrate dns to use internal/errors
PR-URL: #14212 Refs: #11273 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 3566195 commit 9cb390d

File tree

8 files changed

+147
-56
lines changed

8 files changed

+147
-56
lines changed

doc/api/errors.md

+8
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,10 @@ Used when `Console` is instantiated without `stdout` stream or when `stdout` or
596596

597597
Used when the native call from `process.cpuUsage` cannot be processed properly.
598598

599+
<a id="ERR_DNS_SET_SERVERS_FAILED"></a>
600+
601+
Used when `c-ares` failed to set the DNS server.
602+
599603
<a id="ERR_FALSY_VALUE_REJECTION"></a>
600604
### ERR_FALSY_VALUE_REJECTION
601605

@@ -685,6 +689,10 @@ Used when an attempt is made to send an unsupported "handle" over an IPC
685689
communication channel to a child process. See [`child.send()`] and
686690
[`process.send()`] for more information.
687691

692+
<a id="ERR_INVALID_IP_ADDRESS"></a>
693+
694+
Used when an IP address is not valid.
695+
688696
<a id="ERR_INVALID_OPT_VALUE"></a>
689697
### ERR_INVALID_OPT_VALUE
690698

lib/dns.js

+18-15
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const cares = process.binding('cares_wrap');
2727
const uv = process.binding('uv');
2828
const internalNet = require('internal/net');
2929
const { customPromisifyArgs } = require('internal/util');
30+
const errors = require('internal/errors');
3031

3132
const GetAddrInfoReqWrap = cares.GetAddrInfoReqWrap;
3233
const GetNameInfoReqWrap = cares.GetNameInfoReqWrap;
@@ -126,13 +127,13 @@ function lookup(hostname, options, callback) {
126127

127128
// Parse arguments
128129
if (hostname && typeof hostname !== 'string') {
129-
throw new TypeError('Invalid arguments: ' +
130-
'hostname must be a string or falsey');
130+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'hostname',
131+
['string', 'falsey'], hostname);
131132
} else if (typeof options === 'function') {
132133
callback = options;
133134
family = 0;
134135
} else if (typeof callback !== 'function') {
135-
throw new TypeError('Invalid arguments: callback must be passed');
136+
throw new errors.TypeError('ERR_INVALID_CALLBACK');
136137
} else if (options !== null && typeof options === 'object') {
137138
hints = options.hints >>> 0;
138139
family = options.family >>> 0;
@@ -142,14 +143,14 @@ function lookup(hostname, options, callback) {
142143
hints !== cares.AI_ADDRCONFIG &&
143144
hints !== cares.AI_V4MAPPED &&
144145
hints !== (cares.AI_ADDRCONFIG | cares.AI_V4MAPPED)) {
145-
throw new TypeError('Invalid argument: hints must use valid flags');
146+
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', 'hints', hints);
146147
}
147148
} else {
148149
family = options >>> 0;
149150
}
150151

151152
if (family !== 0 && family !== 4 && family !== 6)
152-
throw new TypeError('Invalid argument: family must be 4 or 6');
153+
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', 'family', family);
153154

154155
if (!hostname) {
155156
if (all) {
@@ -200,16 +201,16 @@ function onlookupservice(err, host, service) {
200201
// lookupService(address, port, callback)
201202
function lookupService(host, port, callback) {
202203
if (arguments.length !== 3)
203-
throw new Error('Invalid arguments');
204+
throw new errors.TypeError('ERR_MISSING_ARGS', 'host', 'port', 'callback');
204205

205206
if (isIP(host) === 0)
206-
throw new TypeError('"host" argument needs to be a valid IP address');
207+
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', 'host', host);
207208

208209
if (!isLegalPort(port))
209-
throw new TypeError(`"port" should be >= 0 and < 65536, got "${port}"`);
210+
throw new errors.RangeError('ERR_SOCKET_BAD_PORT');
210211

211212
if (typeof callback !== 'function')
212-
throw new TypeError('"callback" argument must be a function');
213+
throw new errors.TypeError('ERR_INVALID_CALLBACK');
213214

214215
port = +port;
215216

@@ -250,9 +251,10 @@ function resolver(bindingName) {
250251
}
251252

252253
if (typeof name !== 'string') {
253-
throw new Error('"name" argument must be a string');
254+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'name',
255+
'string', name);
254256
} else if (typeof callback !== 'function') {
255-
throw new Error('"callback" argument must be a function');
257+
throw new errors.TypeError('ERR_INVALID_CALLBACK');
256258
}
257259

258260
var req = new QueryReqWrap();
@@ -290,13 +292,14 @@ function resolve(hostname, rrtype, callback) {
290292
resolver = resolveMap.A;
291293
callback = rrtype;
292294
} else {
293-
throw new TypeError('"rrtype" argument must be a string');
295+
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'rrtype',
296+
'string', rrtype);
294297
}
295298

296299
if (typeof resolver === 'function') {
297300
return resolver(hostname, callback);
298301
} else {
299-
throw new Error(`Unknown type "${rrtype}"`);
302+
throw new errors.TypeError('ERR_INVALID_OPT_VALUE', 'rrtype', rrtype);
300303
}
301304
}
302305

@@ -344,7 +347,7 @@ function setServers(servers) {
344347
return newSet.push([ipVersion, s, parseInt(p)]);
345348
}
346349

347-
throw new Error(`IP address is not properly formatted: ${serv}`);
350+
throw new errors.Error('ERR_INVALID_IP_ADDRESS', serv);
348351
});
349352

350353
const errorNumber = cares.setServers(newSet);
@@ -354,7 +357,7 @@ function setServers(servers) {
354357
cares.setServers(orig.join(','));
355358

356359
var err = cares.strerror(errorNumber);
357-
throw new Error(`c-ares failed to set servers: "${err}" [${servers}]`);
360+
throw new errors.Error('ERR_DNS_SET_SERVERS_FAILED', err, servers);
358361
}
359362
}
360363

lib/internal/errors.js

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ E('ERR_CHILD_CLOSED_BEFORE_REPLY', 'Child closed before reply received');
106106
E('ERR_CONSOLE_WRITABLE_STREAM',
107107
'Console expects a writable stream instance for %s');
108108
E('ERR_CPU_USAGE', 'Unable to obtain cpu usage %s');
109+
E('ERR_DNS_SET_SERVERS_FAILED', (err, servers) =>
110+
`c-ares failed to set servers: "${err}" [${servers}]`);
109111
E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value');
110112
E('ERR_HTTP_HEADERS_SENT',
111113
'Cannot render headers after they are sent to the client');
@@ -129,6 +131,7 @@ E('ERR_INVALID_FILE_URL_HOST',
129131
'File URL host must be "localhost" or empty on %s');
130132
E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s');
131133
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent');
134+
E('ERR_INVALID_IP_ADDRESS', 'Invalid IP address: %s');
132135
E('ERR_INVALID_OPT_VALUE',
133136
(name, value) => {
134137
return `The value "${String(value)}" is invalid for option "${name}"`;

test/parallel/test-c-ares.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,21 @@ dns.lookup('::1', common.mustCall((error, result, addressType) => {
4646
assert.strictEqual(6, addressType);
4747
}));
4848

49-
// Try calling resolve with an unsupported type.
50-
assert.throws(() => dns.resolve('www.google.com', 'HI'), /Unknown type/);
51-
52-
// Try calling resolve with an unsupported type that's an object key
53-
assert.throws(() => dns.resolve('www.google.com', 'toString'), /Unknown type/);
49+
[
50+
// Try calling resolve with an unsupported type.
51+
'HI',
52+
// Try calling resolve with an unsupported type that's an object key
53+
'toString'
54+
].forEach((val) => {
55+
common.expectsError(
56+
() => dns.resolve('www.google.com', val),
57+
{
58+
code: 'ERR_INVALID_OPT_VALUE',
59+
type: TypeError,
60+
message: `The value "${val}" is invalid for option "rrtype"`
61+
}
62+
);
63+
});
5464

5565
// Windows doesn't usually have an entry for localhost 127.0.0.1 in
5666
// C:\Windows\System32\drivers\etc\hosts

test/parallel/test-dns-lookup.js

+23-5
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,49 @@ cares.getaddrinfo = () => process.binding('uv').UV_ENOENT;
99

1010
assert.throws(() => {
1111
dns.lookup(1, {});
12-
}, /^TypeError: Invalid arguments: hostname must be a string or falsey$/);
12+
}, common.expectsError({
13+
code: 'ERR_INVALID_ARG_TYPE',
14+
type: TypeError,
15+
message: /^The "hostname" argument must be one of type string or falsey/
16+
}));
1317

1418
assert.throws(() => {
1519
dns.lookup(false, 'cb');
16-
}, /^TypeError: Invalid arguments: callback must be passed$/);
20+
}, common.expectsError({
21+
code: 'ERR_INVALID_CALLBACK',
22+
type: TypeError
23+
}));
1724

1825
assert.throws(() => {
1926
dns.lookup(false, 'options', 'cb');
20-
}, /^TypeError: Invalid arguments: callback must be passed$/);
27+
}, common.expectsError({
28+
code: 'ERR_INVALID_CALLBACK',
29+
type: TypeError
30+
}));
2131

2232
assert.throws(() => {
2333
dns.lookup(false, {
2434
hints: 100,
2535
family: 0,
2636
all: false
2737
}, common.mustNotCall());
28-
}, /^TypeError: Invalid argument: hints must use valid flags$/);
38+
}, common.expectsError({
39+
code: 'ERR_INVALID_OPT_VALUE',
40+
type: TypeError,
41+
message: 'The value "100" is invalid for option "hints"'
42+
}));
2943

3044
assert.throws(() => {
3145
dns.lookup(false, {
3246
hints: 0,
3347
family: 20,
3448
all: false
3549
}, common.mustNotCall());
36-
}, /^TypeError: Invalid argument: family must be 4 or 6$/);
50+
}, common.expectsError({
51+
code: 'ERR_INVALID_OPT_VALUE',
52+
type: TypeError,
53+
message: 'The value "20" is invalid for option "family"'
54+
}));
3755

3856
assert.doesNotThrow(() => {
3957
dns.lookup(false, {

test/parallel/test-dns-regress-7070.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,19 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
'use strict';
23-
require('../common');
23+
const common = require('../common');
2424
const assert = require('assert');
2525
const dns = require('dns');
2626

2727
// Should not raise assertion error. Issue #7070
2828
assert.throws(() => dns.resolveNs([]), // bad name
29-
/^Error: "name" argument must be a string$/);
29+
common.expectsError({
30+
code: 'ERR_INVALID_ARG_TYPE',
31+
type: TypeError,
32+
message: /^The "name" argument must be of type string/
33+
}));
3034
assert.throws(() => dns.resolveNs(''), // bad callback
31-
/^Error: "callback" argument must be a function$/);
35+
common.expectsError({
36+
code: 'ERR_INVALID_CALLBACK',
37+
type: TypeError
38+
}));

test/parallel/test-dns.js

+65-25
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,16 @@ const goog = [
6868
];
6969
assert.doesNotThrow(() => dns.setServers(goog));
7070
assert.deepStrictEqual(dns.getServers(), goog);
71-
assert.throws(() => dns.setServers(['foobar']),
72-
/^Error: IP address is not properly formatted: foobar$/);
73-
assert.throws(() => dns.setServers(['127.0.0.1:va']),
74-
/^Error: IP address is not properly formatted: 127\.0\.0\.1:va$/);
71+
assert.throws(() => dns.setServers(['foobar']), common.expectsError({
72+
code: 'ERR_INVALID_IP_ADDRESS',
73+
type: Error,
74+
message: 'Invalid IP address: foobar'
75+
}));
76+
assert.throws(() => dns.setServers(['127.0.0.1:va']), common.expectsError({
77+
code: 'ERR_INVALID_IP_ADDRESS',
78+
type: Error,
79+
message: 'Invalid IP address: 127.0.0.1:va'
80+
}));
7581
assert.deepStrictEqual(dns.getServers(), goog);
7682

7783
const goog6 = [
@@ -105,12 +111,20 @@ assert.deepStrictEqual(dns.getServers(), []);
105111

106112
assert.throws(() => {
107113
dns.resolve('example.com', [], common.mustNotCall());
108-
}, /^TypeError: "rrtype" argument must be a string$/);
114+
}, common.expectsError({
115+
code: 'ERR_INVALID_ARG_TYPE',
116+
type: TypeError,
117+
message: 'The "rrtype" argument must be of type string. ' +
118+
'Received type object'
119+
}));
109120

110121
// dns.lookup should accept only falsey and string values
111122
{
112-
const errorReg =
113-
/^TypeError: Invalid arguments: hostname must be a string or falsey$/;
123+
const errorReg = common.expectsError({
124+
code: 'ERR_INVALID_ARG_TYPE',
125+
type: TypeError,
126+
message: /^The "hostname" argument must be one of type string or falsey/
127+
}, 5);
114128

115129
assert.throws(() => dns.lookup({}, common.mustNotCall()), errorReg);
116130

@@ -156,13 +170,21 @@ assert.throws(() => {
156170
assert.throws(() => {
157171
dns.lookup('nodejs.org', { hints: (dns.V4MAPPED | dns.ADDRCONFIG) + 1 },
158172
common.mustNotCall());
159-
}, /^TypeError: Invalid argument: hints must use valid flags$/);
160-
161-
assert.throws(() => dns.lookup('nodejs.org'),
162-
/^TypeError: Invalid arguments: callback must be passed$/);
163-
164-
assert.throws(() => dns.lookup('nodejs.org', 4),
165-
/^TypeError: Invalid arguments: callback must be passed$/);
173+
}, common.expectsError({
174+
code: 'ERR_INVALID_OPT_VALUE',
175+
type: TypeError,
176+
message: /The value "\d+" is invalid for option "hints"/
177+
}));
178+
179+
assert.throws(() => dns.lookup('nodejs.org'), common.expectsError({
180+
code: 'ERR_INVALID_CALLBACK',
181+
type: TypeError
182+
}));
183+
184+
assert.throws(() => dns.lookup('nodejs.org', 4), common.expectsError({
185+
code: 'ERR_INVALID_CALLBACK',
186+
type: TypeError
187+
}));
166188

167189
assert.doesNotThrow(() => dns.lookup('', { family: 4, hints: 0 },
168190
common.mustCall()));
@@ -183,25 +205,43 @@ assert.doesNotThrow(() => {
183205
}, common.mustCall());
184206
});
185207

186-
assert.throws(() => dns.lookupService('0.0.0.0'),
187-
/^Error: Invalid arguments$/);
188-
189-
assert.throws(() => dns.lookupService('fasdfdsaf', 0, common.mustNotCall()),
190-
/^TypeError: "host" argument needs to be a valid IP address$/);
208+
assert.throws(() => dns.lookupService('0.0.0.0'), common.expectsError({
209+
code: 'ERR_MISSING_ARGS',
210+
type: TypeError,
211+
message: 'The "host", "port", and "callback" arguments must be specified'
212+
}));
191213

214+
const invalidHost = 'fasdfdsaf';
215+
assert.throws(() => {
216+
dns.lookupService(invalidHost, 0, common.mustNotCall());
217+
}, common.expectsError({
218+
code: 'ERR_INVALID_OPT_VALUE',
219+
type: TypeError,
220+
message: `The value "${invalidHost}" is invalid for option "host"`
221+
}));
222+
223+
const badPortMsg = common.expectsError({
224+
code: 'ERR_SOCKET_BAD_PORT',
225+
type: RangeError,
226+
message: 'Port should be > 0 and < 65536'
227+
}, 4);
192228
assert.throws(() => dns.lookupService('0.0.0.0', null, common.mustNotCall()),
193-
/^TypeError: "port" should be >= 0 and < 65536, got "null"$/);
229+
badPortMsg);
194230

195231
assert.throws(
196232
() => dns.lookupService('0.0.0.0', undefined, common.mustNotCall()),
197-
/^TypeError: "port" should be >= 0 and < 65536, got "undefined"$/
233+
badPortMsg
198234
);
199235

200236
assert.throws(() => dns.lookupService('0.0.0.0', 65538, common.mustNotCall()),
201-
/^TypeError: "port" should be >= 0 and < 65536, got "65538"$/);
237+
badPortMsg);
202238

203239
assert.throws(() => dns.lookupService('0.0.0.0', 'test', common.mustNotCall()),
204-
/^TypeError: "port" should be >= 0 and < 65536, got "test"$/);
240+
badPortMsg);
205241

206-
assert.throws(() => dns.lookupService('0.0.0.0', 80, null),
207-
/^TypeError: "callback" argument must be a function$/);
242+
assert.throws(() => {
243+
dns.lookupService('0.0.0.0', 80, null);
244+
}, common.expectsError({
245+
code: 'ERR_INVALID_CALLBACK',
246+
type: TypeError
247+
}));

0 commit comments

Comments
 (0)