Skip to content

Commit c0c5ac6

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: #19191 PR-URL: #18546 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent ae81a04 commit c0c5ac6

File tree

10 files changed

+141
-86
lines changed

10 files changed

+141
-86
lines changed

lib/dgram.js

Lines changed: 2 additions & 2 deletions
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

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@
2121

2222
'use strict';
2323

24-
const util = require('util');
25-
2624
const cares = process.binding('cares_wrap');
27-
const uv = process.binding('uv');
2825
const { isLegalPort } = require('internal/net');
2926
const { customPromisifyArgs } = require('internal/util');
27+
const errors = require('internal/errors');
3028

3129
const {
3230
GetAddrInfoReqWrap,
@@ -36,30 +34,6 @@ const {
3634
isIP
3735
} = cares;
3836

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

63+
const dnsException = errors.dnsException;
8964

9065
function onlookup(err, addresses) {
9166
if (err) {
92-
return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
67+
return this.callback(dnsException(err, 'getaddrinfo', this.hostname));
9368
}
9469
if (this.family) {
9570
this.callback(null, addresses[0], this.family);
@@ -101,7 +76,7 @@ function onlookup(err, addresses) {
10176

10277
function onlookupall(err, addresses) {
10378
if (err) {
104-
return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
79+
return this.callback(dnsException(err, 'getaddrinfo', this.hostname));
10580
}
10681

10782
var family = this.family;
@@ -181,7 +156,7 @@ function lookup(hostname, options, callback) {
181156

182157
var err = cares.getaddrinfo(req, hostname, family, hints, verbatim);
183158
if (err) {
184-
process.nextTick(callback, errnoException(err, 'getaddrinfo', hostname));
159+
process.nextTick(callback, dnsException(err, 'getaddrinfo', hostname));
185160
return {};
186161
}
187162
return req;
@@ -193,7 +168,7 @@ Object.defineProperty(lookup, customPromisifyArgs,
193168

194169
function onlookupservice(err, host, service) {
195170
if (err)
196-
return this.callback(errnoException(err, 'getnameinfo', this.host));
171+
return this.callback(dnsException(err, 'getnameinfo', this.host));
197172

198173
this.callback(null, host, service);
199174
}
@@ -222,7 +197,7 @@ function lookupService(host, port, callback) {
222197
req.oncomplete = onlookupservice;
223198

224199
var err = cares.getnameinfo(req, host, port);
225-
if (err) throw errnoException(err, 'getnameinfo', host);
200+
if (err) throw dnsException(err, 'getnameinfo', host);
226201
return req;
227202
}
228203

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

237212
if (err)
238-
this.callback(errnoException(err, this.bindingName, this.hostname));
213+
this.callback(dnsException(err, this.bindingName, this.hostname));
239214
else
240215
this.callback(null, result);
241216
}
@@ -272,7 +247,7 @@ function resolver(bindingName) {
272247
req.oncomplete = onresolve;
273248
req.ttl = !!(options && options.ttl);
274249
var err = this._handle[bindingName](req, name);
275-
if (err) throw errnoException(err, bindingName);
250+
if (err) throw dnsException(err, bindingName);
276251
return req;
277252
}
278253
Object.defineProperty(query, 'name', { value: bindingName });

lib/fs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const { kMaxLength } = require('buffer');
5959
const isWindows = process.platform === 'win32';
6060

6161
const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
62-
const errnoException = util._errnoException;
62+
const errnoException = errors.errnoException;
6363

6464
function getOptions(options, defaultOptions) {
6565
if (options === null || options === undefined ||

lib/internal/child_process.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const SocketList = require('internal/socket_list');
1818
const { convertToValidSignal } = require('internal/util');
1919
const { isUint8Array } = require('internal/util/types');
2020

21-
const errnoException = util._errnoException;
21+
const errnoException = errors.errnoException;
2222
const { SocketListSend, SocketListReceive } = SocketList;
2323

2424
const MAX_HANDLE_RETRANSMISSIONS = 3;

lib/internal/errors.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
const kCode = Symbol('code');
1212
const messages = new Map();
1313

14+
const {
15+
UV_EAI_MEMORY,
16+
UV_EAI_NODATA,
17+
UV_EAI_NONAME
18+
} = process.binding('uv');
1419
const { defineProperty } = Object;
1520

1621
// Lazily loaded
@@ -22,6 +27,14 @@ function lazyUtil() {
2227
return util_;
2328
}
2429

30+
var internalUtil = null;
31+
function lazyInternalUtil() {
32+
if (!internalUtil) {
33+
internalUtil = require('internal/util');
34+
}
35+
return internalUtil;
36+
}
37+
2538
function makeNodeError(Base) {
2639
return class NodeError extends Base {
2740
constructor(key, ...args) {
@@ -125,7 +138,110 @@ function E(sym, val) {
125138
messages.set(sym, typeof val === 'function' ? val : String(val));
126139
}
127140

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

lib/internal/http2/core.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,7 @@ class Http2Stream extends Duplex {
16471647
req.async = false;
16481648
const err = createWriteReq(req, handle, data, encoding);
16491649
if (err)
1650-
return this.destroy(util._errnoException(err, 'write', req.error), cb);
1650+
return this.destroy(errors.errnoException(err, 'write', req.error), cb);
16511651
trackWriteState(this, req.bytes);
16521652
}
16531653

@@ -1690,7 +1690,7 @@ class Http2Stream extends Duplex {
16901690
}
16911691
const err = handle.writev(req, chunks);
16921692
if (err)
1693-
return this.destroy(util._errnoException(err, 'write', req.error), cb);
1693+
return this.destroy(errors.errnoException(err, 'write', req.error), cb);
16941694
trackWriteState(this, req.bytes);
16951695
}
16961696

lib/internal/process.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
const errors = require('internal/errors');
34
const util = require('util');
45
const constants = process.binding('constants').os.signals;
56

@@ -180,7 +181,7 @@ function setupKillAndExit() {
180181
}
181182

182183
if (err)
183-
throw util._errnoException(err, 'kill');
184+
throw errors.errnoException(err, 'kill');
184185

185186
return true;
186187
};
@@ -211,7 +212,7 @@ function setupSignalHandlers() {
211212
const err = wrap.start(signum);
212213
if (err) {
213214
wrap.close();
214-
throw util._errnoException(err, 'uv_signal_start');
215+
throw errors.errnoException(err, 'uv_signal_start');
215216
}
216217

217218
signalWraps[type] = wrap;

lib/net.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ const dns = require('dns');
4848
// reasons it's lazy loaded.
4949
var cluster = null;
5050

51-
const errnoException = util._errnoException;
52-
const exceptionWithHostPort = util._exceptionWithHostPort;
51+
const errnoException = errors.errnoException;
52+
const exceptionWithHostPort = errors.exceptionWithHostPort;
5353

5454
function noop() {}
5555

lib/tty.js

Lines changed: 3 additions & 5 deletions
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)