diff --git a/lib/net.js b/lib/net.js index 0882c4f5d25b9a..061d7b959d300e 100644 --- a/lib/net.js +++ b/lib/net.js @@ -63,6 +63,25 @@ function isPipeName(s) { return util.isString(s) && toNumber(s) === false; } +// format exceptions +function detailedException(err, syscall, address, port, additional) { + var details; + if (port && port > 0) { + details = address + ':' + port; + } else { + details = address; + } + + if (additional) { + details += ' - Local (' + additional + ')'; + } + var ex = errnoException(err, syscall, details); + ex.address = address; + if (port) { + ex.port = port; + } + return ex; +} exports.createServer = function() { return new Server(arguments[0], arguments[1]); @@ -755,7 +774,7 @@ function afterWrite(status, handle, req, err) { } if (status < 0) { - var ex = errnoException(status, 'write', err); + var ex = detailedException(status, 'write', req.address, req.port); debug('write failure', ex); self._destroy(ex, req.cb); return; @@ -817,28 +836,46 @@ function connect(self, address, port, addressType, localAddress, localPort) { err = bind(localAddress, localPort); if (err) { - self._destroy(errnoException(err, 'bind')); + var ex = detailedException(err, 'bind', localAddress, localPort); + self._destroy(ex); return; } } - var req = { oncomplete: afterConnect }; + var req = { + oncomplete: afterConnect, + port: undefined, + address: undefined, + localAddress: undefined, + localPort: undefined + }; if (addressType === 6 || addressType === 4) { port = port | 0; 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')); + self._getsockname(); + var details; + if (self._sockname) { + ex.localAddress = self._sockname.address; + ex.localPort = self._sockname.port; + details = ex.localAddress + ':' + ex.localPort; + } + var ex = detailedException(err, 'connect', address, port, details); + self._destroy(ex); } } @@ -921,6 +958,9 @@ 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() { + err.host = options.host; + err.port = options.port; + err.message = err.message + ' ' + options.host + ':' + options.port; self.emit('error', err); self._destroy(); }); @@ -988,7 +1028,18 @@ function afterConnect(status, handle, req, readable, writable) { } else { self._connecting = false; - self._destroy(errnoException(status, 'connect')); + var details; + if (req.localAddress && req.localPort) { + ex.localAddress = req.localAddress; + ex.localPort = req.localPort; + details = ex.localAddress + ':' + ex.localPort; + } + var ex = detailedException(status, + 'connect', + req.address, + req.port, + details); + self._destroy(ex); } } @@ -1117,7 +1168,7 @@ 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 error = detailedException(rval, 'listen', address, port); process.nextTick(function() { self.emit('error', error); }); @@ -1134,7 +1185,7 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) { var err = _listen(self._handle, backlog); if (err) { - var ex = errnoException(err, 'listen'); + var ex = detailedException(err, 'listen', address, port); self._handle.close(); self._handle = null; process.nextTick(function() { @@ -1182,8 +1233,10 @@ function listen(self, address, port, addressType, backlog, fd, exclusive) { err = uv.UV_EADDRINUSE; } - if (err) - return self.emit('error', errnoException(err, 'bind')); + if (err) { + var ex = detailedException(err, 'bind', address, port); + return self.emit('error', ex); + } self._handle = handle; self._listen2(address, port, addressType, backlog, fd); diff --git a/test/simple/test-net-better-error-messages-listen-path.js b/test/simple/test-net-better-error-messages-listen-path.js new file mode 100644 index 00000000000000..fcc3062a814f68 --- /dev/null +++ b/test/simple/test-net-better-error-messages-listen-path.js @@ -0,0 +1,9 @@ +var common = require('../common'); +var assert = require('assert'); +var net = require('net'); +var fp = '/blah/fadfa'; +var server = net.createServer(assert.fail); +server.listen(fp, assert.fail); +server.on('error', common.mustCall(function(e) { + assert.equal(e.address, fp) +})); diff --git a/test/simple/test-net-better-error-messages-listen.js b/test/simple/test-net-better-error-messages-listen.js new file mode 100644 index 00000000000000..9c7766bd4f4e3d --- /dev/null +++ b/test/simple/test-net-better-error-messages-listen.js @@ -0,0 +1,11 @@ +var common = require('../common'); +var assert = require('assert'); +var net = require('net'); + +var server = net.createServer(assert.fail); +server.listen(1, '1.1.1.1', assert.fail); +server.on('error', common.mustCall(function(e) { + assert.equal(e.address, '1.1.1.1'); + assert.equal(e.port, 1); + assert.equal(e.syscall, 'listen'); +})); diff --git a/test/simple/test-net-better-error-messages-path.js b/test/simple/test-net-better-error-messages-path.js new file mode 100644 index 00000000000000..dea4a10459edab --- /dev/null +++ b/test/simple/test-net-better-error-messages-path.js @@ -0,0 +1,12 @@ +var common = require('../common'); +var net = require('net'); +var assert = require('assert'); +var fp = '/tmp/fadagagsdfgsdf'; +var c = net.connect(fp); + +c.on('connect', assert.fail); + +c.on('error', common.mustCall(function(e) { + assert.equal(e.code, 'ENOENT'); + assert.equal(e.message, 'connect ENOENT ' + fp); +})); diff --git a/test/simple/test-net-better-error-messages-port-hostname.js b/test/simple/test-net-better-error-messages-port-hostname.js new file mode 100644 index 00000000000000..3817dbb92ff1e2 --- /dev/null +++ b/test/simple/test-net-better-error-messages-port-hostname.js @@ -0,0 +1,13 @@ +var common = require('../common'); +var net = require('net'); +var assert = require('assert'); + +var c = net.createConnection(common.PORT, 'blah.blah'); + +c.on('connect', assert.fail); + +c.on('error', common.mustCall(function(e) { + assert.equal(e.code, 'ENOTFOUND'); + assert.equal(e.port, common.PORT); + assert.equal(e.hostname, 'blah.blah'); +})); diff --git a/test/simple/test-net-better-error-messages-port.js b/test/simple/test-net-better-error-messages-port.js new file mode 100644 index 00000000000000..a8c16a70385bb3 --- /dev/null +++ b/test/simple/test-net-better-error-messages-port.js @@ -0,0 +1,13 @@ +var common = require('../common'); +var net = require('net'); +var assert = require('assert'); + +var c = net.createConnection(common.PORT); + +c.on('connect', assert.fail); + +c.on('error', common.mustCall(function(e) { + assert.equal(e.code, 'ECONNREFUSED'); + assert.equal(e.port, common.PORT); + assert.equal(e.address, '127.0.0.1'); +}));