Skip to content

Commit 1246902

Browse files
joyeecheungMylesBorins
authored andcommitted
errors: move error creation helpers to errors.js
This commit moves error creation helpers scattered around under lib/ into lib/internal/errors.js in the hope of being clearer about the differences of errors that we throw into the user land. - Move util._errnoException and util._exceptionWithHostPort into internal/errors.js and simplify their logic so it's clearer what the properties these helpers create. - Move the errnoException helper in dns.js to internal/errors.js into internal/errors.js and rename it to dnsException. Simplify it's logic so it no longer calls errnoException and skips the unnecessary argument checks. Backport-PR-URL: #18916 PR-URL: #18546 Reviewed-By: James M Snell <[email protected]>
1 parent 8e31bf4 commit 1246902

File tree

10 files changed

+139
-89
lines changed

10 files changed

+139
-89
lines changed

lib/dgram.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ const SEND_BUFFER = false;
4545
// Lazily loaded
4646
var cluster = null;
4747

48-
const errnoException = util._errnoException;
49-
const exceptionWithHostPort = util._exceptionWithHostPort;
48+
const errnoException = errors.errnoException;
49+
const exceptionWithHostPort = errors.exceptionWithHostPort;
5050

5151

5252
function lookup4(lookup, address, callback) {

lib/dns.js

+8-38
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,10 @@
2121

2222
'use strict';
2323

24-
const util = require('util');
25-
2624
const cares = process.binding('cares_wrap');
2725
const { isLegalPort } = require('internal/net');
2826
const { customPromisifyArgs } = require('internal/util');
2927
const errors = require('internal/errors');
30-
const {
31-
UV_EAI_MEMORY,
32-
UV_EAI_NODATA,
33-
UV_EAI_NONAME
34-
} = process.binding('uv');
3528

3629
const {
3730
GetAddrInfoReqWrap,
@@ -41,30 +34,6 @@ const {
4134
isIP
4235
} = cares;
4336

44-
function errnoException(err, syscall, hostname) {
45-
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
46-
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
47-
if (err === UV_EAI_MEMORY ||
48-
err === UV_EAI_NODATA ||
49-
err === UV_EAI_NONAME) {
50-
err = 'ENOTFOUND';
51-
}
52-
var ex = null;
53-
if (typeof err === 'string') { // c-ares error code.
54-
const errHost = hostname ? ` ${hostname}` : '';
55-
ex = new Error(`${syscall} ${err}${errHost}`);
56-
ex.code = err;
57-
ex.errno = err;
58-
ex.syscall = syscall;
59-
} else {
60-
ex = util._errnoException(err, syscall);
61-
}
62-
if (hostname) {
63-
ex.hostname = hostname;
64-
}
65-
return ex;
66-
}
67-
6837
const IANA_DNS_PORT = 53;
6938
const digits = [
7039
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
@@ -91,10 +60,11 @@ function isIPv4(str) {
9160
return (str.length > 3 && str.charCodeAt(3) === 46/*'.'*/);
9261
}
9362

63+
const dnsException = errors.dnsException;
9464

9565
function onlookup(err, addresses) {
9666
if (err) {
97-
return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
67+
return this.callback(dnsException(err, 'getaddrinfo', this.hostname));
9868
}
9969
if (this.family) {
10070
this.callback(null, addresses[0], this.family);
@@ -106,7 +76,7 @@ function onlookup(err, addresses) {
10676

10777
function onlookupall(err, addresses) {
10878
if (err) {
109-
return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
79+
return this.callback(dnsException(err, 'getaddrinfo', this.hostname));
11080
}
11181

11282
var family = this.family;
@@ -186,7 +156,7 @@ function lookup(hostname, options, callback) {
186156

187157
var err = cares.getaddrinfo(req, hostname, family, hints, verbatim);
188158
if (err) {
189-
process.nextTick(callback, errnoException(err, 'getaddrinfo', hostname));
159+
process.nextTick(callback, dnsException(err, 'getaddrinfo', hostname));
190160
return {};
191161
}
192162
return req;
@@ -198,7 +168,7 @@ Object.defineProperty(lookup, customPromisifyArgs,
198168

199169
function onlookupservice(err, host, service) {
200170
if (err)
201-
return this.callback(errnoException(err, 'getnameinfo', this.host));
171+
return this.callback(dnsException(err, 'getnameinfo', this.host));
202172

203173
this.callback(null, host, service);
204174
}
@@ -227,7 +197,7 @@ function lookupService(host, port, callback) {
227197
req.oncomplete = onlookupservice;
228198

229199
var err = cares.getnameinfo(req, host, port);
230-
if (err) throw errnoException(err, 'getnameinfo', host);
200+
if (err) throw dnsException(err, 'getnameinfo', host);
231201
return req;
232202
}
233203

@@ -240,7 +210,7 @@ function onresolve(err, result, ttls) {
240210
result = result.map((address, index) => ({ address, ttl: ttls[index] }));
241211

242212
if (err)
243-
this.callback(errnoException(err, this.bindingName, this.hostname));
213+
this.callback(dnsException(err, this.bindingName, this.hostname));
244214
else
245215
this.callback(null, result);
246216
}
@@ -278,7 +248,7 @@ function resolver(bindingName) {
278248
req.oncomplete = onresolve;
279249
req.ttl = !!(options && options.ttl);
280250
var err = this._handle[bindingName](req, name);
281-
if (err) throw errnoException(err, bindingName);
251+
if (err) throw dnsException(err, bindingName);
282252
return req;
283253
}
284254
Object.defineProperty(query, 'name', { value: bindingName });

lib/fs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const { kMaxLength } = require('buffer');
6363
const isWindows = process.platform === 'win32';
6464

6565
const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
66-
const errnoException = util._errnoException;
66+
const errnoException = errors.errnoException;
6767

6868
let truncateWarn = true;
6969

lib/internal/child_process.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const {
2929
UV_ESRCH
3030
} = process.binding('uv');
3131

32-
const errnoException = util._errnoException;
32+
const errnoException = errors.errnoException;
3333
const { SocketListSend, SocketListReceive } = SocketList;
3434

3535
const MAX_HANDLE_RETRANSMISSIONS = 3;

lib/internal/errors.js

+116
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
const kCode = Symbol('code');
1414
const messages = new Map();
1515

16+
const {
17+
UV_EAI_MEMORY,
18+
UV_EAI_NODATA,
19+
UV_EAI_NONAME
20+
} = process.binding('uv');
1621
const { kMaxLength } = process.binding('buffer');
1722
const { defineProperty } = Object;
1823

@@ -25,6 +30,14 @@ function lazyUtil() {
2530
return util_;
2631
}
2732

33+
var internalUtil = null;
34+
function lazyInternalUtil() {
35+
if (!internalUtil) {
36+
internalUtil = require('internal/util');
37+
}
38+
return internalUtil;
39+
}
40+
2841
function makeNodeError(Base) {
2942
return class NodeError extends Base {
3043
constructor(key, ...args) {
@@ -128,7 +141,110 @@ function E(sym, val) {
128141
messages.set(sym, typeof val === 'function' ? val : String(val));
129142
}
130143

144+
/**
145+
* This used to be util._errnoException().
146+
*
147+
* @param {number} err - A libuv error number
148+
* @param {string} syscall
149+
* @param {string} [original]
150+
* @returns {Error}
151+
*/
152+
function errnoException(err, syscall, original) {
153+
// TODO(joyeecheung): We have to use the type-checked
154+
// getSystemErrorName(err) to guard against invalid arguments from users.
155+
// This can be replaced with [ code ] = errmap.get(err) when this method
156+
// is no longer exposed to user land.
157+
const code = lazyUtil().getSystemErrorName(err);
158+
const message = original ?
159+
`${syscall} ${code} ${original}` : `${syscall} ${code}`;
160+
161+
const ex = new Error(message);
162+
// TODO(joyeecheung): errno is supposed to err, like in uvException
163+
ex.code = ex.errno = code;
164+
ex.syscall = syscall;
165+
166+
Error.captureStackTrace(ex, errnoException);
167+
return ex;
168+
}
169+
170+
/**
171+
* This used to be util._exceptionWithHostPort().
172+
*
173+
* @param {number} err - A libuv error number
174+
* @param {string} syscall
175+
* @param {string} address
176+
* @param {number} [port]
177+
* @param {string} [additional]
178+
* @returns {Error}
179+
*/
180+
function exceptionWithHostPort(err, syscall, address, port, additional) {
181+
// TODO(joyeecheung): We have to use the type-checked
182+
// getSystemErrorName(err) to guard against invalid arguments from users.
183+
// This can be replaced with [ code ] = errmap.get(err) when this method
184+
// is no longer exposed to user land.
185+
const code = lazyUtil().getSystemErrorName(err);
186+
let details = '';
187+
if (port && port > 0) {
188+
details = ` ${address}:${port}`;
189+
} else if (address) {
190+
details = ` ${address}`;
191+
}
192+
if (additional) {
193+
details += ` - Local (${additional})`;
194+
}
195+
196+
const ex = new Error(`${syscall} ${code}${details}`);
197+
// TODO(joyeecheung): errno is supposed to err, like in uvException
198+
ex.code = ex.errno = code;
199+
ex.syscall = syscall;
200+
ex.address = address;
201+
if (port) {
202+
ex.port = port;
203+
}
204+
205+
Error.captureStackTrace(ex, exceptionWithHostPort);
206+
return ex;
207+
}
208+
209+
/**
210+
* @param {number|string} err - A libuv error number or a c-ares error code
211+
* @param {string} syscall
212+
* @param {string} [hostname]
213+
* @returns {Error}
214+
*/
215+
function dnsException(err, syscall, hostname) {
216+
const ex = new Error();
217+
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
218+
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
219+
if (err === UV_EAI_MEMORY ||
220+
err === UV_EAI_NODATA ||
221+
err === UV_EAI_NONAME) {
222+
err = 'ENOTFOUND'; // Fabricated error name.
223+
}
224+
if (typeof err === 'string') { // c-ares error code.
225+
const errHost = hostname ? ` ${hostname}` : '';
226+
ex.message = `${syscall} ${err}${errHost}`;
227+
// TODO(joyeecheung): errno is supposed to be a number, like in uvException
228+
ex.code = ex.errno = err;
229+
ex.syscall = syscall;
230+
} else { // libuv error number
231+
const code = lazyInternalUtil().getSystemErrorName(err);
232+
ex.message = `${syscall} ${code}`;
233+
// TODO(joyeecheung): errno is supposed to be err, like in uvException
234+
ex.code = ex.errno = code;
235+
ex.syscall = syscall;
236+
}
237+
if (hostname) {
238+
ex.hostname = hostname;
239+
}
240+
Error.captureStackTrace(ex, dnsException);
241+
return ex;
242+
}
243+
131244
module.exports = exports = {
245+
dnsException,
246+
errnoException,
247+
exceptionWithHostPort,
132248
message,
133249
Error: makeNodeError(Error),
134250
TypeError: makeNodeError(TypeError),

lib/internal/http2/core.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,7 @@ class Http2Stream extends Duplex {
16191619
req.async = false;
16201620
const err = createWriteReq(req, handle, data, encoding);
16211621
if (err)
1622-
throw util._errnoException(err, 'write', req.error);
1622+
throw errors.errnoException(err, 'write', req.error);
16231623
trackWriteState(this, req.bytes);
16241624
}
16251625

@@ -1662,7 +1662,7 @@ class Http2Stream extends Duplex {
16621662
}
16631663
const err = handle.writev(req, chunks);
16641664
if (err)
1665-
throw util._errnoException(err, 'write', req.error);
1665+
throw errors.errnoException(err, 'write', req.error);
16661666
trackWriteState(this, req.bytes);
16671667
}
16681668

lib/internal/process.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ function setupKillAndExit() {
170170
}
171171

172172
if (err)
173-
throw util._errnoException(err, 'kill');
173+
throw errors.errnoException(err, 'kill');
174174

175175
return true;
176176
};
@@ -200,7 +200,7 @@ function setupSignalHandlers() {
200200
const err = wrap.start(signum);
201201
if (err) {
202202
wrap.close();
203-
throw util._errnoException(err, 'uv_signal_start');
203+
throw errors.errnoException(err, 'uv_signal_start');
204204
}
205205

206206
signalWraps[type] = wrap;

lib/net.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ const kLastWriteQueueSize = Symbol('lastWriteQueueSize');
5858
// reasons it's lazy loaded.
5959
var cluster = null;
6060

61-
const errnoException = util._errnoException;
62-
const exceptionWithHostPort = util._exceptionWithHostPort;
61+
const errnoException = errors.errnoException;
62+
const exceptionWithHostPort = errors.exceptionWithHostPort;
6363

6464
function noop() {}
6565

lib/tty.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@
2121

2222
'use strict';
2323

24-
const util = require('util');
24+
const { inherits, _extend } = require('util');
2525
const net = require('net');
2626
const { TTY, isTTY } = process.binding('tty_wrap');
27-
const { inherits } = util;
28-
const errnoException = util._errnoException;
2927
const errors = require('internal/errors');
3028
const readline = require('readline');
3129

@@ -40,7 +38,7 @@ function ReadStream(fd, options) {
4038
if (fd >> 0 !== fd || fd < 0)
4139
throw new errors.RangeError('ERR_INVALID_FD', fd);
4240

43-
options = util._extend({
41+
options = _extend({
4442
highWaterMark: 0,
4543
readable: true,
4644
writable: false,
@@ -99,7 +97,7 @@ WriteStream.prototype._refreshSize = function() {
9997
var winSize = new Array(2);
10098
var err = this._handle.getWindowSize(winSize);
10199
if (err) {
102-
this.emit('error', errnoException(err, 'getWindowSize'));
100+
this.emit('error', errors.errnoException(err, 'getWindowSize'));
103101
return;
104102
}
105103
var newCols = winSize[0];

0 commit comments

Comments
 (0)