Skip to content

Commit

Permalink
lib: http server, friendly error messages
Browse files Browse the repository at this point in the history
Improved error message description for the http server binding errors.

Currently changed only in `setupListenHandle`, but needs to be
change all over.

Added new `uvExceptionWithHostPort` function (+export) in
`lib/internal/error.js` that extracts the error message defined by
libuv, using the error code, and returns an error object with the
full error description.

example:
old error message: `listen EADDRINUSE`
new error message: `listen EADDRINUSE: Address already in use`

Removed exportable function `_exceptionWithHostPort` from
`lib/util.js` - exported by accident

Replaced `exceptionWithHostPort` to the new function
`uvExceptionWithHostPort` for a more detailed error.

Fixes: #22936

PR-URL: #22995
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
sagitsofan authored and targos committed Oct 13, 2018
1 parent f681691 commit efe4f5e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
46 changes: 44 additions & 2 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,46 @@ function uvException(ctx) {
return err;
}

/**
* This creates an error compatible with errors produced in the C++
* This function should replace the deprecated
* `exceptionWithHostPort()` function.
*
* @param {number} err - A libuv error number
* @param {string} syscall
* @param {string} address
* @param {number} [port]
* @param {string} [additional]
* @returns {Error}
*/
function uvExceptionWithHostPort(err, syscall, address, port, additional) {
const [ code, uvmsg ] = errmap.get(err);
const message = `${syscall} ${code}: ${uvmsg}`;
let details = '';

if (port && port > 0) {
details = ` ${address}:${port}`;
} else if (address) {
details = ` ${address}`;
}
if (additional) {
details += ` - Local (${additional})`;
}

// eslint-disable-next-line no-restricted-syntax
const ex = new Error(`${message}${details}`);
ex.code = code;
ex.errno = code;
ex.syscall = syscall;
ex.address = address;
if (port) {
ex.port = port;
}

Error.captureStackTrace(ex, uvExceptionWithHostPort);
return ex;
}

/**
* This used to be util._errnoException().
*
Expand Down Expand Up @@ -315,8 +355,9 @@ function errnoException(err, syscall, original) {
}

/**
* This used to be util._exceptionWithHostPort().
*
* Deprecated, new function is `uvExceptionWithHostPort()`
* New function added the error description directly
* from C++. this method for backwards compatibility
* @param {number} err - A libuv error number
* @param {string} syscall
* @param {string} address
Expand Down Expand Up @@ -440,6 +481,7 @@ module.exports = {
errnoException,
exceptionWithHostPort,
uvException,
uvExceptionWithHostPort,
isStackOverflowError,
getMessage,
SystemError,
Expand Down
10 changes: 7 additions & 3 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ const kLastWriteQueueSize = Symbol('lastWriteQueueSize');
let cluster;
let dns;

const { errnoException, exceptionWithHostPort } = errors;
const {
errnoException,
exceptionWithHostPort,
uvExceptionWithHostPort
} = errors;

const {
kTimeout,
Expand Down Expand Up @@ -1266,7 +1270,7 @@ function setupListenHandle(address, port, addressType, backlog, fd) {
rval = createServerHandle(address, port, addressType, fd);

if (typeof rval === 'number') {
var error = exceptionWithHostPort(rval, 'listen', address, port);
var error = uvExceptionWithHostPort(rval, 'listen', address, port);
process.nextTick(emitErrorNT, this, error);
return;
}
Expand All @@ -1283,7 +1287,7 @@ function setupListenHandle(address, port, addressType, backlog, fd) {
var err = this._handle.listen(backlog || 511);

if (err) {
var ex = exceptionWithHostPort(err, 'listen', address, port);
var ex = uvExceptionWithHostPort(err, 'listen', address, port);
this._handle.close();
this._handle = null;
defaultTriggerAsyncIdScope(this[async_id_symbol],
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-net-server-listen-handle.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ if (!common.isWindows) { // Windows doesn't support {fd: <n>}
net.createServer()
.listen({ fd }, common.mustNotCall())
.on('error', common.mustCall(function(err) {
assert.strictEqual(String(err), 'Error: listen EINVAL');
assert.strictEqual(String(err), 'Error: listen EINVAL: invalid argument');
this.close();
}));
}

0 comments on commit efe4f5e

Please sign in to comment.