From 11e10d16d4e9955e9201e2c5d6c4b39e30763613 Mon Sep 17 00:00:00 2001 From: Gabriel Castro Date: Thu, 18 Oct 2018 13:13:39 -0400 Subject: [PATCH] Catch sub process crashes --- lib/process/master.js | 11 ++++++ lib/process/sandbox.js | 3 ++ test/fixtures/fixture_processor_crash.js | 17 +++++++++ test/test_sandboxed_process.js | 46 ++++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 test/fixtures/fixture_processor_crash.js diff --git a/lib/process/master.js b/lib/process/master.js index 787289849..bf5899d63 100644 --- a/lib/process/master.js +++ b/lib/process/master.js @@ -75,6 +75,17 @@ process.on('message', function(msg) { } }); +process.on('uncaughtException', function(err) { + if (!err.message) { + err = new Error(err); + } + process.send({ + cmd: 'failed', + value: err + }); + throw err; +}); + function wrapJob(job) { job.progress = function(progress) { process.send({ diff --git a/lib/process/sandbox.js b/lib/process/sandbox.js index 9a85e4de0..52ecbce5a 100644 --- a/lib/process/sandbox.js +++ b/lib/process/sandbox.js @@ -31,6 +31,9 @@ module.exports = function(processFile, childPool) { } child.on('message', handler); + child.on('exit', function(exitCode) { + reject(new Error('Unexpected exit code: ' + exitCode)); + }); }); return done.finally(function() { diff --git a/test/fixtures/fixture_processor_crash.js b/test/fixtures/fixture_processor_crash.js new file mode 100644 index 000000000..24ad5e98a --- /dev/null +++ b/test/fixtures/fixture_processor_crash.js @@ -0,0 +1,17 @@ +/** + * A processor file to be used in tests. + * + */ + +var Promise = require('bluebird'); + +module.exports = function(job) { + setTimeout(function() { + if (typeof job.data.exitCode !== 'number') { + throw new Error('boom!'); + } + process.exit(job.data.exitCode); + }, 100); + + return new Promise(function() {}); +}; diff --git a/test/test_sandboxed_process.js b/test/test_sandboxed_process.js index a743d9b0a..ab312cc48 100644 --- a/test/test_sandboxed_process.js +++ b/test/test_sandboxed_process.js @@ -270,6 +270,52 @@ describe('sandboxed process', function() { queue.add({ foo: 'bar' }); }); + it('should fail if the process crashes', function() { + queue.process(__dirname + '/fixtures/fixture_processor_crash.js'); + + return queue + .add({}) + .then(function(job) { + return job.finished().reflect(); + }) + .then(function(inspection) { + expect(inspection.isRejected()).to.be.eql(true); + expect(inspection.reason().message).to.be.eql('boom!'); + }); + }); + + it('should fail if the process exits 0', function() { + queue.process(__dirname + '/fixtures/fixture_processor_crash.js'); + + return queue + .add({ exitCode: 0 }) + .then(function(job) { + return job.finished().reflect(); + }) + .then(function(inspection) { + expect(inspection.isRejected()).to.be.eql(true); + expect(inspection.reason().message).to.be.eql( + 'Unexpected exit code: 0' + ); + }); + }); + + it('should fail if the process exits non-0', function() { + queue.process(__dirname + '/fixtures/fixture_processor_crash.js'); + + return queue + .add({ exitCode: 1 }) + .then(function(job) { + return job.finished().reflect(); + }) + .then(function(inspection) { + expect(inspection.isRejected()).to.be.eql(true); + expect(inspection.reason().message).to.be.eql( + 'Unexpected exit code: 1' + ); + }); + }); + it('should remove exited process', function(done) { queue.process(__dirname + '/fixtures/fixture_processor_exit.js');