From 56afb7b481db26ec6f86dcd3806c8bfafe78e40e Mon Sep 17 00:00:00 2001 From: Ouyang Yadong Date: Sat, 27 Oct 2018 15:44:50 +0800 Subject: [PATCH] net: `net.Server.listen()` avoid operations on `null` when fail When `net.Server` fails to create a new handle, an error shall be emitted in the next tick. Therefore, we make `net.Server.listen()` directly return to avoid following operations on `null` `this._handle`. Fixes: https://github.com/nodejs/node/issues/23917 PR-URL: https://github.com/nodejs/node/pull/23920 Reviewed-By: Richard Lau Reviewed-By: Daniel Bevenius --- lib/net.js | 7 +++++++ test/parallel/test-net-server-listen-path.js | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/net.js b/lib/net.js index cc048eccbbd85b..48a8bc069901e2 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)); + })); + }); +}