Skip to content

Commit

Permalink
net: give better error messages
Browse files Browse the repository at this point in the history
Add address and/or port to errors where applicable for better reporting.

See nodejs#7005

Use util.format instead of string concatenation

Also move some logic into util._errnoException. Passing an object as
the fourth parameter to util._errnoException will now extend the
returned error.
  • Loading branch information
evanlucas committed Jun 5, 2014
1 parent 2f86275 commit ed85b77
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 9 deletions.
61 changes: 53 additions & 8 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,12 @@ function afterWrite(status, handle, req, err) {
}

if (status < 0) {
var ex = errnoException(status, 'write', err);
err = util.format('%s %s:%s', err || '', req.address, req.port);
var additions = {
address: req.address
};
if (req.port) additions.port = req.port;
var ex = errnoException(status, 'write', err, additions);
debug('write failure', ex);
self._destroy(ex, req.cb);
return;
Expand Down Expand Up @@ -825,7 +830,13 @@ function connect(self, address, port, addressType, localAddress, localPort) {
err = bind(localAddress, localPort);

if (err) {
self._destroy(errnoException(err, 'bind'));
var details = util.format('%s:%s', address, port || '');
var additions = {
address: address
};
if (port) additions.port = port;
var ex = errnoException(err, 'bind', details, additions);
self._destroy(ex);
return;
}
}
Expand All @@ -836,17 +847,26 @@ function connect(self, address, port, addressType, localAddress, localPort) {
if (port <= 0 || port > 65535)
throw new RangeError('Port should be > 0 and < 65536');

req.port = port;
req.address = address;
if (addressType === 6) {
err = self._handle.connect6(req, address, port);
} else if (addressType === 4) {
err = self._handle.connect(req, address, port);
}
} else {
req.address = address;
err = self._handle.connect(req, address, afterConnect);
}

if (err) {
self._destroy(errnoException(err, 'connect'));
var details = util.format('%s:%s', address, port || '');
var additions = {
address: address
};
if (port) additions.port = port;
var ex = errnoException(err, 'connect', details, additions);
self._destroy(ex);
}
}

Expand Down Expand Up @@ -919,6 +939,7 @@ Socket.prototype.connect = function(options, cb) {
// There are no event listeners registered yet so defer the
// error event to the next tick.
process.nextTick(function() {
if (options.port) err.port = options.port;
self.emit('error', err);
self._destroy();
});
Expand Down Expand Up @@ -986,7 +1007,13 @@ function afterConnect(status, handle, req, readable, writable) {

} else {
self._connecting = false;
self._destroy(errnoException(status, 'connect'));
var details = util.format('%s:%s', req.address, req.port || '');
var additions = {
address: req.address
};
if (req.port) additions.port = req.port;
var ex = errnoException(status, 'connect', details, additions);
self._destroy(ex);
}
}

Expand Down Expand Up @@ -1127,7 +1154,12 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
debug('_listen2: create a handle');
var rval = createServerHandle(address, port, addressType, fd);
if (util.isNumber(rval)) {
var error = errnoException(rval, 'listen');
var details = util.format('%s:%s', address, port > 0 ? port : '');
var additions = {
address: address
};
if (port > 0) additions.port = port;
var error = errnoException(rval, 'listen', details, additions);
process.nextTick(function() {
self.emit('error', error);
});
Expand All @@ -1147,7 +1179,12 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
err = _listen(self._handle, backlog);

if (err) {
var ex = errnoException(err, 'listen');
var details = util.format('%s:%s', address, port > 0 ? port : '');
var additions = {
address: address
};
if (port > 0) additions.port = port;
var ex = errnoException(err, 'listen', details, additions);
self._handle.close();
self._handle = null;
process.nextTick(function() {
Expand Down Expand Up @@ -1191,8 +1228,16 @@ function listen(self, address, port, addressType, backlog, fd) {
err = uv.UV_EADDRINUSE;
}

if (err)
return self.emit('error', errnoException(err, 'bind'));
if (err) {
var details = util.format('%s:%s', address, port > 0 ? port : '');
var additions = {
address: address
};
if (port > 0) additions.port = port;
var ex = errnoException(err, 'bind', details, additions);
return self.emit('error', ex);
}


self._handle = handle;
self._listen2(address, port, addressType, backlog, fd);
Expand Down
4 changes: 3 additions & 1 deletion lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ exports.pump = exports.deprecate(function(readStream, writeStream, callback) {


var uv;
exports._errnoException = function(err, syscall, original) {
exports._errnoException = function(err, syscall, original, additions) {
if (isUndefined(uv)) uv = process.binding('uv');
var errname = uv.errname(err);
var message = syscall + ' ' + errname;
Expand All @@ -743,5 +743,7 @@ exports._errnoException = function(err, syscall, original) {
e.code = errname;
e.errno = errname;
e.syscall = syscall;
if (additions)
e = exports._extend(e, additions);
return e;
};
39 changes: 39 additions & 0 deletions test/simple/test-net-better-error-messages-listen-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var common = require('../common');
var assert = require('assert');
var net = require('net');
var gotError = false;
var fp = '/blah/fadfa';
var server = net.createServer(function(socket) {
});
server.listen(fp, function() {
assert(false);
});
server.on('error', function(e) {
console.error('error', e);
gotError = true;
});

process.on('exit', function() {
assert(gotError);
});
41 changes: 41 additions & 0 deletions test/simple/test-net-better-error-messages-listen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var common = require('../common');
var assert = require('assert');
var net = require('net');
var gotError = false;

var server = net.createServer(function(socket) {
});
server.listen(1, '1.1.1.1', function() { // EACCESS or EADDRNOTAVAIL
assert(false);
});
server.on('error', function(e) {
console.error('error', e);
gotError = true;
assert.equal('1.1.1.1', e.address);
assert.equal(1, e.port);
});

process.on('exit', function() {
assert(gotError);
});
45 changes: 45 additions & 0 deletions test/simple/test-net-better-error-messages-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.



var common = require('../common');
var net = require('net');
var assert = require('assert');
var fp = '/tmp/fadagagsdfgsdf';
var c = net.connect(fp);

c.on('connect', function() {
console.error('connected?!');
assert.ok(false);
});

var gotError = false;
c.on('error', function(e) {
console.error('couldn\'t connect.', e);
gotError = true;
assert.equal('ENOENT', e.code);
assert.equal(fp, e.address);
});

process.on('exit', function() {
assert.ok(gotError);
});
46 changes: 46 additions & 0 deletions test/simple/test-net-better-error-messages-port-hostname.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.



var common = require('../common');
var net = require('net');
var assert = require('assert');

var c = net.createConnection(common.PORT, 'blah');

c.on('connect', function() {
console.error('connected?!');
assert.ok(false);
});

var gotError = false;
c.on('error', function(e) {
console.error('couldn\'t connect.', e);
gotError = true;
assert.equal('ENOTFOUND', e.code);
assert.equal(common.PORT, e.port);
assert.equal('blah', e.hostname);
});

process.on('exit', function() {
assert.ok(gotError);
});
46 changes: 46 additions & 0 deletions test/simple/test-net-better-error-messages-port.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.



var common = require('../common');
var net = require('net');
var assert = require('assert');

var c = net.createConnection(common.PORT);

c.on('connect', function() {
console.error('connected?!');
assert.ok(false);
});

var gotError = false;
c.on('error', function(e) {
console.error('couldn\'t connect.', e);
gotError = true;
assert.equal('ECONNREFUSED', e.code);
assert.equal(common.PORT, e.port);
assert.equal('127.0.0.1', e.address);
});

process.on('exit', function() {
assert.ok(gotError);
});

0 comments on commit ed85b77

Please sign in to comment.