diff --git a/lib/net.js b/lib/net.js index 33ce1f74eb2fba..a0597bb0a08d64 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1435,6 +1435,13 @@ Server.prototype.listen = function(...args) { backlog = options.backlog || backlogFromArgs; listenInCluster(this, pipeName, -1, -1, backlog, undefined, options.exclusive); + + if (!this._handle) { + // Failed and an error shall be emitted in the next tick. + // Therefore, we directly return. + return this; + } + let mode = 0; if (options.readableAll === true) mode |= PipeConstants.UV_READABLE; diff --git a/test/parallel/test-net-server-listen-path.js b/test/parallel/test-net-server-listen-path.js index cc73c3fd438abe..cc7c6678b04224 100644 --- a/test/parallel/test-net-server-listen-path.js +++ b/test/parallel/test-net-server-listen-path.js @@ -69,3 +69,23 @@ function randomPipePath() { srv.close(); })); } + +// Test should emit "error" events when listening fails. +{ + const handlePath = randomPipePath(); + const srv1 = net.createServer().listen({ path: handlePath }, () => { + // As the handlePath is in use, binding to the same address again should + // make the server emit an 'EADDRINUSE' error. + const srv2 = net.createServer() + .listen({ + path: handlePath, + writableAll: true, + }, common.mustNotCall()); + + srv2.on('error', common.mustCall((err) => { + srv1.close(); + assert.strictEqual(err.code, 'EADDRINUSE'); + assert(/^listen EADDRINUSE: address already in use/.test(err.message)); + })); + }); +}