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. PR-URL: https://github.com/nodejs/node/pull/18546 Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
030384833f
commit
c0762c2f54
@ -45,8 +45,8 @@ const SEND_BUFFER = false;
|
|||||||
// Lazily loaded
|
// Lazily loaded
|
||||||
var cluster = null;
|
var cluster = null;
|
||||||
|
|
||||||
const errnoException = util._errnoException;
|
const errnoException = errors.errnoException;
|
||||||
const exceptionWithHostPort = util._exceptionWithHostPort;
|
const exceptionWithHostPort = errors.exceptionWithHostPort;
|
||||||
|
|
||||||
|
|
||||||
function lookup4(lookup, address, callback) {
|
function lookup4(lookup, address, callback) {
|
||||||
|
47
lib/dns.js
47
lib/dns.js
@ -21,17 +21,10 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const util = require('util');
|
|
||||||
|
|
||||||
const cares = process.binding('cares_wrap');
|
const cares = process.binding('cares_wrap');
|
||||||
const { isIP, isIPv4, isLegalPort } = require('internal/net');
|
const { isIP, isIPv4, isLegalPort } = require('internal/net');
|
||||||
const { customPromisifyArgs } = require('internal/util');
|
const { customPromisifyArgs } = require('internal/util');
|
||||||
const errors = require('internal/errors');
|
const errors = require('internal/errors');
|
||||||
const {
|
|
||||||
UV_EAI_MEMORY,
|
|
||||||
UV_EAI_NODATA,
|
|
||||||
UV_EAI_NONAME
|
|
||||||
} = process.binding('uv');
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
GetAddrInfoReqWrap,
|
GetAddrInfoReqWrap,
|
||||||
@ -40,36 +33,12 @@ const {
|
|||||||
ChannelWrap,
|
ChannelWrap,
|
||||||
} = cares;
|
} = cares;
|
||||||
|
|
||||||
function errnoException(err, syscall, hostname) {
|
|
||||||
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
|
|
||||||
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
|
|
||||||
if (err === UV_EAI_MEMORY ||
|
|
||||||
err === UV_EAI_NODATA ||
|
|
||||||
err === UV_EAI_NONAME) {
|
|
||||||
err = 'ENOTFOUND';
|
|
||||||
}
|
|
||||||
var ex = null;
|
|
||||||
if (typeof err === 'string') { // c-ares error code.
|
|
||||||
const errHost = hostname ? ` ${hostname}` : '';
|
|
||||||
ex = new Error(`${syscall} ${err}${errHost}`);
|
|
||||||
ex.code = err;
|
|
||||||
ex.errno = err;
|
|
||||||
ex.syscall = syscall;
|
|
||||||
} else {
|
|
||||||
ex = util._errnoException(err, syscall);
|
|
||||||
}
|
|
||||||
if (hostname) {
|
|
||||||
ex.hostname = hostname;
|
|
||||||
}
|
|
||||||
return ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
const IANA_DNS_PORT = 53;
|
const IANA_DNS_PORT = 53;
|
||||||
|
const dnsException = errors.dnsException;
|
||||||
|
|
||||||
function onlookup(err, addresses) {
|
function onlookup(err, addresses) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
|
return this.callback(dnsException(err, 'getaddrinfo', this.hostname));
|
||||||
}
|
}
|
||||||
if (this.family) {
|
if (this.family) {
|
||||||
this.callback(null, addresses[0], this.family);
|
this.callback(null, addresses[0], this.family);
|
||||||
@ -81,7 +50,7 @@ function onlookup(err, addresses) {
|
|||||||
|
|
||||||
function onlookupall(err, addresses) {
|
function onlookupall(err, addresses) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return this.callback(errnoException(err, 'getaddrinfo', this.hostname));
|
return this.callback(dnsException(err, 'getaddrinfo', this.hostname));
|
||||||
}
|
}
|
||||||
|
|
||||||
var family = this.family;
|
var family = this.family;
|
||||||
@ -161,7 +130,7 @@ function lookup(hostname, options, callback) {
|
|||||||
|
|
||||||
var err = cares.getaddrinfo(req, hostname, family, hints, verbatim);
|
var err = cares.getaddrinfo(req, hostname, family, hints, verbatim);
|
||||||
if (err) {
|
if (err) {
|
||||||
process.nextTick(callback, errnoException(err, 'getaddrinfo', hostname));
|
process.nextTick(callback, dnsException(err, 'getaddrinfo', hostname));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return req;
|
return req;
|
||||||
@ -173,7 +142,7 @@ Object.defineProperty(lookup, customPromisifyArgs,
|
|||||||
|
|
||||||
function onlookupservice(err, host, service) {
|
function onlookupservice(err, host, service) {
|
||||||
if (err)
|
if (err)
|
||||||
return this.callback(errnoException(err, 'getnameinfo', this.host));
|
return this.callback(dnsException(err, 'getnameinfo', this.host));
|
||||||
|
|
||||||
this.callback(null, host, service);
|
this.callback(null, host, service);
|
||||||
}
|
}
|
||||||
@ -202,7 +171,7 @@ function lookupService(host, port, callback) {
|
|||||||
req.oncomplete = onlookupservice;
|
req.oncomplete = onlookupservice;
|
||||||
|
|
||||||
var err = cares.getnameinfo(req, host, port);
|
var err = cares.getnameinfo(req, host, port);
|
||||||
if (err) throw errnoException(err, 'getnameinfo', host);
|
if (err) throw dnsException(err, 'getnameinfo', host);
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +184,7 @@ function onresolve(err, result, ttls) {
|
|||||||
result = result.map((address, index) => ({ address, ttl: ttls[index] }));
|
result = result.map((address, index) => ({ address, ttl: ttls[index] }));
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
this.callback(errnoException(err, this.bindingName, this.hostname));
|
this.callback(dnsException(err, this.bindingName, this.hostname));
|
||||||
else
|
else
|
||||||
this.callback(null, result);
|
this.callback(null, result);
|
||||||
}
|
}
|
||||||
@ -253,7 +222,7 @@ function resolver(bindingName) {
|
|||||||
req.oncomplete = onresolve;
|
req.oncomplete = onresolve;
|
||||||
req.ttl = !!(options && options.ttl);
|
req.ttl = !!(options && options.ttl);
|
||||||
var err = this._handle[bindingName](req, name);
|
var err = this._handle[bindingName](req, name);
|
||||||
if (err) throw errnoException(err, bindingName);
|
if (err) throw dnsException(err, bindingName);
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
Object.defineProperty(query, 'name', { value: bindingName });
|
Object.defineProperty(query, 'name', { value: bindingName });
|
||||||
|
@ -62,7 +62,7 @@ const { kMaxLength } = require('buffer');
|
|||||||
const isWindows = process.platform === 'win32';
|
const isWindows = process.platform === 'win32';
|
||||||
|
|
||||||
const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
|
const DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
|
||||||
const errnoException = util._errnoException;
|
const errnoException = errors.errnoException;
|
||||||
|
|
||||||
let truncateWarn = true;
|
let truncateWarn = true;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ const {
|
|||||||
UV_ESRCH
|
UV_ESRCH
|
||||||
} = process.binding('uv');
|
} = process.binding('uv');
|
||||||
|
|
||||||
const errnoException = util._errnoException;
|
const errnoException = errors.errnoException;
|
||||||
const { SocketListSend, SocketListReceive } = SocketList;
|
const { SocketListSend, SocketListReceive } = SocketList;
|
||||||
|
|
||||||
const MAX_HANDLE_RETRANSMISSIONS = 3;
|
const MAX_HANDLE_RETRANSMISSIONS = 3;
|
||||||
|
@ -18,7 +18,12 @@ var green = '';
|
|||||||
var red = '';
|
var red = '';
|
||||||
var white = '';
|
var white = '';
|
||||||
|
|
||||||
const { errmap } = process.binding('uv');
|
const {
|
||||||
|
errmap,
|
||||||
|
UV_EAI_MEMORY,
|
||||||
|
UV_EAI_NODATA,
|
||||||
|
UV_EAI_NONAME
|
||||||
|
} = process.binding('uv');
|
||||||
const { kMaxLength } = process.binding('buffer');
|
const { kMaxLength } = process.binding('buffer');
|
||||||
const { defineProperty } = Object;
|
const { defineProperty } = Object;
|
||||||
|
|
||||||
@ -33,6 +38,14 @@ function lazyUtil() {
|
|||||||
return util_;
|
return util_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var internalUtil = null;
|
||||||
|
function lazyInternalUtil() {
|
||||||
|
if (!internalUtil) {
|
||||||
|
internalUtil = require('internal/util');
|
||||||
|
}
|
||||||
|
return internalUtil;
|
||||||
|
}
|
||||||
|
|
||||||
function makeNodeError(Base) {
|
function makeNodeError(Base) {
|
||||||
return class NodeError extends Base {
|
return class NodeError extends Base {
|
||||||
constructor(key, ...args) {
|
constructor(key, ...args) {
|
||||||
@ -356,10 +369,15 @@ function E(sym, val) {
|
|||||||
messages.set(sym, typeof val === 'function' ? val : String(val));
|
messages.set(sym, typeof val === 'function' ? val : String(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This creates an error compatible with errors produced in UVException
|
/**
|
||||||
// using the context collected in CollectUVExceptionInfo
|
* This creates an error compatible with errors produced in the C++
|
||||||
// The goal is to migrate them to ERR_* errors later when
|
* function UVException using a context object with data assembled in C++.
|
||||||
// compatibility is not a concern
|
* The goal is to migrate them to ERR_* errors later when compatibility is
|
||||||
|
* not a concern.
|
||||||
|
*
|
||||||
|
* @param {Object} ctx
|
||||||
|
* @returns {Error}
|
||||||
|
*/
|
||||||
function uvException(ctx) {
|
function uvException(ctx) {
|
||||||
const err = new Error();
|
const err = new Error();
|
||||||
|
|
||||||
@ -389,7 +407,110 @@ function uvException(ctx) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This used to be util._errnoException().
|
||||||
|
*
|
||||||
|
* @param {number} err - A libuv error number
|
||||||
|
* @param {string} syscall
|
||||||
|
* @param {string} [original]
|
||||||
|
* @returns {Error}
|
||||||
|
*/
|
||||||
|
function errnoException(err, syscall, original) {
|
||||||
|
// TODO(joyeecheung): We have to use the type-checked
|
||||||
|
// getSystemErrorName(err) to guard against invalid arguments from users.
|
||||||
|
// This can be replaced with [ code ] = errmap.get(err) when this method
|
||||||
|
// is no longer exposed to user land.
|
||||||
|
const code = lazyUtil().getSystemErrorName(err);
|
||||||
|
const message = original ?
|
||||||
|
`${syscall} ${code} ${original}` : `${syscall} ${code}`;
|
||||||
|
|
||||||
|
const ex = new Error(message);
|
||||||
|
// TODO(joyeecheung): errno is supposed to err, like in uvException
|
||||||
|
ex.code = ex.errno = code;
|
||||||
|
ex.syscall = syscall;
|
||||||
|
|
||||||
|
Error.captureStackTrace(ex, errnoException);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This used to be util._exceptionWithHostPort().
|
||||||
|
*
|
||||||
|
* @param {number} err - A libuv error number
|
||||||
|
* @param {string} syscall
|
||||||
|
* @param {string} address
|
||||||
|
* @param {number} [port]
|
||||||
|
* @param {string} [additional]
|
||||||
|
* @returns {Error}
|
||||||
|
*/
|
||||||
|
function exceptionWithHostPort(err, syscall, address, port, additional) {
|
||||||
|
// TODO(joyeecheung): We have to use the type-checked
|
||||||
|
// getSystemErrorName(err) to guard against invalid arguments from users.
|
||||||
|
// This can be replaced with [ code ] = errmap.get(err) when this method
|
||||||
|
// is no longer exposed to user land.
|
||||||
|
const code = lazyUtil().getSystemErrorName(err);
|
||||||
|
let details = '';
|
||||||
|
if (port && port > 0) {
|
||||||
|
details = ` ${address}:${port}`;
|
||||||
|
} else if (address) {
|
||||||
|
details = ` ${address}`;
|
||||||
|
}
|
||||||
|
if (additional) {
|
||||||
|
details += ` - Local (${additional})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ex = new Error(`${syscall} ${code}${details}`);
|
||||||
|
// TODO(joyeecheung): errno is supposed to err, like in uvException
|
||||||
|
ex.code = ex.errno = code;
|
||||||
|
ex.syscall = syscall;
|
||||||
|
ex.address = address;
|
||||||
|
if (port) {
|
||||||
|
ex.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error.captureStackTrace(ex, exceptionWithHostPort);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number|string} err - A libuv error number or a c-ares error code
|
||||||
|
* @param {string} syscall
|
||||||
|
* @param {string} [hostname]
|
||||||
|
* @returns {Error}
|
||||||
|
*/
|
||||||
|
function dnsException(err, syscall, hostname) {
|
||||||
|
const ex = new Error();
|
||||||
|
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
|
||||||
|
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
|
||||||
|
if (err === UV_EAI_MEMORY ||
|
||||||
|
err === UV_EAI_NODATA ||
|
||||||
|
err === UV_EAI_NONAME) {
|
||||||
|
err = 'ENOTFOUND'; // Fabricated error name.
|
||||||
|
}
|
||||||
|
if (typeof err === 'string') { // c-ares error code.
|
||||||
|
const errHost = hostname ? ` ${hostname}` : '';
|
||||||
|
ex.message = `${syscall} ${err}${errHost}`;
|
||||||
|
// TODO(joyeecheung): errno is supposed to be a number, like in uvException
|
||||||
|
ex.code = ex.errno = err;
|
||||||
|
ex.syscall = syscall;
|
||||||
|
} else { // libuv error number
|
||||||
|
const code = lazyInternalUtil().getSystemErrorName(err);
|
||||||
|
ex.message = `${syscall} ${code}`;
|
||||||
|
// TODO(joyeecheung): errno is supposed to be err, like in uvException
|
||||||
|
ex.code = ex.errno = code;
|
||||||
|
ex.syscall = syscall;
|
||||||
|
}
|
||||||
|
if (hostname) {
|
||||||
|
ex.hostname = hostname;
|
||||||
|
}
|
||||||
|
Error.captureStackTrace(ex, dnsException);
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = exports = {
|
module.exports = exports = {
|
||||||
|
dnsException,
|
||||||
|
errnoException,
|
||||||
|
exceptionWithHostPort,
|
||||||
uvException,
|
uvException,
|
||||||
message,
|
message,
|
||||||
Error: makeNodeError(Error),
|
Error: makeNodeError(Error),
|
||||||
|
@ -1631,7 +1631,7 @@ class Http2Stream extends Duplex {
|
|||||||
req.async = false;
|
req.async = false;
|
||||||
const err = createWriteReq(req, handle, data, encoding);
|
const err = createWriteReq(req, handle, data, encoding);
|
||||||
if (err)
|
if (err)
|
||||||
throw util._errnoException(err, 'write', req.error);
|
throw errors.errnoException(err, 'write', req.error);
|
||||||
trackWriteState(this, req.bytes);
|
trackWriteState(this, req.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1674,7 +1674,7 @@ class Http2Stream extends Duplex {
|
|||||||
}
|
}
|
||||||
const err = handle.writev(req, chunks);
|
const err = handle.writev(req, chunks);
|
||||||
if (err)
|
if (err)
|
||||||
throw util._errnoException(err, 'write', req.error);
|
throw errors.errnoException(err, 'write', req.error);
|
||||||
trackWriteState(this, req.bytes);
|
trackWriteState(this, req.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ function setupKillAndExit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
throw util._errnoException(err, 'kill');
|
throw errors.errnoException(err, 'kill');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -200,7 +200,7 @@ function setupSignalHandlers() {
|
|||||||
const err = wrap.start(signum);
|
const err = wrap.start(signum);
|
||||||
if (err) {
|
if (err) {
|
||||||
wrap.close();
|
wrap.close();
|
||||||
throw util._errnoException(err, 'uv_signal_start');
|
throw errors.errnoException(err, 'uv_signal_start');
|
||||||
}
|
}
|
||||||
|
|
||||||
signalWraps[type] = wrap;
|
signalWraps[type] = wrap;
|
||||||
|
@ -59,8 +59,8 @@ const kLastWriteQueueSize = Symbol('lastWriteQueueSize');
|
|||||||
// reasons it's lazy loaded.
|
// reasons it's lazy loaded.
|
||||||
var cluster = null;
|
var cluster = null;
|
||||||
|
|
||||||
const errnoException = util._errnoException;
|
const errnoException = errors.errnoException;
|
||||||
const exceptionWithHostPort = util._exceptionWithHostPort;
|
const exceptionWithHostPort = errors.exceptionWithHostPort;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
kTimeout,
|
kTimeout,
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { inherits, _errnoException, _extend } = require('util');
|
const { inherits, _extend } = require('util');
|
||||||
const net = require('net');
|
const net = require('net');
|
||||||
const { TTY, isTTY } = process.binding('tty_wrap');
|
const { TTY, isTTY } = process.binding('tty_wrap');
|
||||||
const errors = require('internal/errors');
|
const errors = require('internal/errors');
|
||||||
@ -178,7 +178,7 @@ WriteStream.prototype._refreshSize = function() {
|
|||||||
const winSize = new Array(2);
|
const winSize = new Array(2);
|
||||||
const err = this._handle.getWindowSize(winSize);
|
const err = this._handle.getWindowSize(winSize);
|
||||||
if (err) {
|
if (err) {
|
||||||
this.emit('error', _errnoException(err, 'getWindowSize'));
|
this.emit('error', errors.errnoException(err, 'getWindowSize'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [newCols, newRows] = winSize;
|
const [newCols, newRows] = winSize;
|
||||||
|
38
lib/util.js
38
lib/util.js
@ -1058,40 +1058,6 @@ function error(...args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _errnoException(err, syscall, original) {
|
|
||||||
const name = getSystemErrorName(err);
|
|
||||||
var message = `${syscall} ${name}`;
|
|
||||||
if (original)
|
|
||||||
message += ` ${original}`;
|
|
||||||
const e = new Error(message);
|
|
||||||
e.code = e.errno = name;
|
|
||||||
e.syscall = syscall;
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _exceptionWithHostPort(err,
|
|
||||||
syscall,
|
|
||||||
address,
|
|
||||||
port,
|
|
||||||
additional) {
|
|
||||||
var details;
|
|
||||||
if (port && port > 0) {
|
|
||||||
details = `${address}:${port}`;
|
|
||||||
} else {
|
|
||||||
details = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (additional) {
|
|
||||||
details += ` - Local (${additional})`;
|
|
||||||
}
|
|
||||||
var ex = exports._errnoException(err, syscall, details);
|
|
||||||
ex.address = address;
|
|
||||||
if (port) {
|
|
||||||
ex.port = port;
|
|
||||||
}
|
|
||||||
return ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
function callbackifyOnRejected(reason, cb) {
|
function callbackifyOnRejected(reason, cb) {
|
||||||
// `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
|
// `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
|
||||||
// Because `null` is a special error value in callbacks which means "no error
|
// Because `null` is a special error value in callbacks which means "no error
|
||||||
@ -1152,8 +1118,8 @@ function getSystemErrorName(err) {
|
|||||||
|
|
||||||
// Keep the `exports =` so that various functions can still be monkeypatched
|
// Keep the `exports =` so that various functions can still be monkeypatched
|
||||||
module.exports = exports = {
|
module.exports = exports = {
|
||||||
_errnoException,
|
_errnoException: errors.errnoException,
|
||||||
_exceptionWithHostPort,
|
_exceptionWithHostPort: errors.exceptionWithHostPort,
|
||||||
_extend,
|
_extend,
|
||||||
callbackify,
|
callbackify,
|
||||||
debuglog,
|
debuglog,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user