diff --git a/lib/cluster.js b/lib/cluster.js index d60366aaf179c8..175645f713f701 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -719,7 +719,11 @@ function workerInit() { const handle = handles[key]; delete handles[key]; waitingCount++; - handle.owner.close(checkWaitingCount); + + if (handle.owner) + handle.owner.close(checkWaitingCount); + else + handle.close(checkWaitingCount); } checkWaitingCount(); diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 73c641c116d24e..789c29ef777042 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -715,7 +715,9 @@ function handleMessage(target, message, handle) { message.cmd.slice(0, INTERNAL_PREFIX.length) === INTERNAL_PREFIX) { eventName = 'internalMessage'; } - target.emit(eventName, message, handle); + process.nextTick(() => { + target.emit(eventName, message, handle); + }); } function nop() { } diff --git a/test/parallel/test-cluster-ipc-throw.js b/test/parallel/test-cluster-ipc-throw.js new file mode 100644 index 00000000000000..f2e7f2822c7315 --- /dev/null +++ b/test/parallel/test-cluster-ipc-throw.js @@ -0,0 +1,23 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); +const cluster = require('cluster'); + +cluster.schedulingPolicy = cluster.SCHED_RR; + +const server = http.createServer(); + +if (cluster.isMaster) { + server.listen(common.PORT); + const worker = cluster.fork(); + worker.on('exit', common.mustCall(() => { + server.close(); + })); +} else { + process.on('uncaughtException', common.mustCall((e) => {})); + server.listen(common.PORT); + server.on('error', common.mustCall((e) => { + cluster.worker.disconnect(); + throw e; + })); +} diff --git a/test/parallel/test-cluster-worker-disconnect-on-error.js b/test/parallel/test-cluster-worker-disconnect-on-error.js new file mode 100644 index 00000000000000..e52f7ddee60993 --- /dev/null +++ b/test/parallel/test-cluster-worker-disconnect-on-error.js @@ -0,0 +1,20 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); +const cluster = require('cluster'); + +cluster.schedulingPolicy = cluster.SCHED_NONE; + +const server = http.createServer(); +if (cluster.isMaster) { + server.listen(common.PORT); + const worker = cluster.fork(); + worker.on('exit', common.mustCall(() => { + server.close(); + })); +} else { + server.listen(common.PORT); + server.on('error', common.mustCall((e) => { + cluster.worker.disconnect(); + })); +}