Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #31 from olivierto/master
Implemented ChildprocessError class to be conform to Promises/A+ spec
  • Loading branch information
patrick-steele-idem committed Mar 29, 2017
2 parents 36c0b8c + 187421b commit 217609b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 52 deletions.
18 changes: 18 additions & 0 deletions lib/ChildProcessError.js
@@ -0,0 +1,18 @@
'use strict';


class ChildProcessError extends Error {
constructor(message, code, childProcess, stdout, stderr) {
super(message);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.code = code;
this.childProcess = childProcess;
this.stdout = stdout;
this.stderr = stderr;
}
}



module.exports = ChildProcessError;
53 changes: 24 additions & 29 deletions lib/index.js
Expand Up @@ -2,6 +2,8 @@
var child_process = require('child_process');
var crossSpawn = require('cross-spawn');
var ChildProcessPromise = require('./ChildProcessPromise');
var ChildProcessError = require('./ChildProcessError');

var slice = Array.prototype.slice;

/**
Expand All @@ -28,8 +30,8 @@ function doExec(method, args) {
err.message += ' `' + commandStr + '` (exited with error code ' + err.code + ')';
err.stdout = stdout;
err.stderr = stderr;

reject(err);
var cpError = new ChildProcessError(err.message, err.code, child_process, stdout, stderr);
reject(cpError);
} else {
resolve({
childProcess: cp,
Expand All @@ -45,24 +47,24 @@ function doExec(method, args) {
}

/**
* `exec` as Promised
*
* @param {String} command
* @param {Object} options
* @return {Promise}
*/
* `exec` as Promised
*
* @param {String} command
* @param {Object} options
* @return {Promise}
*/
function exec() {
return doExec('exec', arguments);
}

/**
* `execFile` as Promised
*
* @param {String} command
* @param {Array} args
* @param {Object} options
* @return {Promise}
*/
* `execFile` as Promised
*
* @param {String} command
* @param {Array} args
* @param {Object} options
* @return {Promise}
*/
function execFile() {
return doExec('execFile', arguments);
}
Expand Down Expand Up @@ -108,32 +110,26 @@ function doSpawn(method, command, args, options) {
if (captureStdout) {
result.stdout = '';

cp.stdout.on('data', function (data) {
cp.stdout.on('data', function(data) {
result.stdout += data;
});
}

if (captureStderr) {
result.stderr = '';

cp.stderr.on('data', function (data) {
cp.stderr.on('data', function(data) {
result.stderr += data;
});
}

cp.on('error', reject);

cp.on('close', function (code) {
cp.on('close', function(code) {
if (successfulExitCodes.indexOf(code) === -1) {
var commandStr = command + (args.length ? (' ' + args.join(' ')) : '');
var err = {
code: code,
message: '`' + commandStr + '` failed with code ' + code,
childProcess: cp,
toString() {
return this.message;
}
};
var message = '`' + commandStr + '` failed with code ' + code;
var err = new ChildProcessError(message, code, cp);

if (captureStderr) {
err.stderr = result.stderr.toString();
Expand All @@ -144,8 +140,7 @@ function doSpawn(method, command, args, options) {
}

reject(err);
}
else {
} else {
result.code = code;
resolve(result);
}
Expand All @@ -167,4 +162,4 @@ function fork(modulePath, args, options) {
exports.exec = exec;
exports.execFile = execFile;
exports.spawn = spawn;
exports.fork = fork;
exports.fork = fork;
58 changes: 35 additions & 23 deletions test/test.js
Expand Up @@ -8,11 +8,14 @@ var path = require('path');
var childProcessPromise = require('../');

var ChildProcessPromise;
var ChildProcessError;

if (require('node-version').major >= 4) {
ChildProcessPromise = require('../lib/ChildProcessPromise');
ChildProcessError = require('../lib/ChildProcessError');
} else {
ChildProcessPromise = require('../lib-es5/ChildProcessPromise');
ChildProcessError = require('../lib-es5/ChildProcessError');
}

var Promise;
Expand Down Expand Up @@ -95,7 +98,7 @@ describe('child-process-promise', function() {
var childProcessPid;

childProcessPromise.exec('echo hello')
.then(function (result) {
.then(function(result) {
var stdout = result.stdout;
var stderr = result.stderr;

Expand All @@ -104,10 +107,10 @@ describe('child-process-promise', function() {
expect(childProcessPid).to.be.a('number');
done();
})
.fail(function (err) {
.fail(function(err) {
console.error('ERROR: ', (err.stack || err));
})
.progress(function (childProcess) {
.progress(function(childProcess) {
childProcessPid = childProcess.pid;
})
.done();
Expand Down Expand Up @@ -168,7 +171,9 @@ describe('child-process-promise', function() {
done(new Error('rejection was expected but it completed successfully!'));
})
.fail(function(e) {
expect(e).to.be.an.instanceof(ChildProcessError);
expect(e.toString()).to.contain(missingFilePath);
expect(e.code).to.equal('ENOENT');
done();
})
.catch(done);
Expand All @@ -178,7 +183,7 @@ describe('child-process-promise', function() {
var childProcessPid;

childProcessPromise.execFile(NODE_PATH, ['--version'])
.then(function (result) {
.then(function(result) {
var stdout = result.stdout;
var stderr = result.stderr;

Expand All @@ -187,7 +192,7 @@ describe('child-process-promise', function() {
expect(childProcessPid).to.be.a('number');
done();
})
.progress(function (childProcess) {
.progress(function(childProcess) {
childProcessPid = childProcess.pid;
})
.done();
Expand Down Expand Up @@ -270,11 +275,12 @@ describe('child-process-promise', function() {
.then(function(result) {
done(new Error('rejection expected!'));
})
.catch(function(result) {
expect(result.stdout).to.equal('');
expect(result.stderr).to.contain(missingFilePath);
expect(result.childProcess).to.be.an('object');
expect(result.childProcess).to.equal(childProcess);
.catch(function(error) {
expect(error).to.be.an.instanceof(ChildProcessError);
expect(error.stdout).to.equal('');
expect(error.stderr).to.contain(missingFilePath);
expect(error.childProcess).to.be.an('object');
expect(error.childProcess).to.equal(childProcess);
done();
})
.done();
Expand All @@ -289,6 +295,7 @@ describe('child-process-promise', function() {
done(new Error('rejection was expected but it completed successfully!'));
})
.catch(function(e) {
expect(e).to.be.an.instanceof(ChildProcessError);
expect(e.toString()).to.contain(missingFilePath);
done();
})
Expand All @@ -304,6 +311,7 @@ describe('child-process-promise', function() {
done(new Error('rejection was expected but it completed successfully!'));
})
.fail(function(e) {
expect(e).to.be.an.instanceof(ChildProcessError);
expect(e.toString()).to.contain(missingFilePath);
done();
})
Expand All @@ -315,14 +323,14 @@ describe('child-process-promise', function() {
var spawnErr = '';
childProcessPromise.spawn('echo', ['hello'])
.progress(function(childProcess) {
childProcess.stdout.on('data', function (data) {
childProcess.stdout.on('data', function(data) {
spawnOut += data;
});
childProcess.stderr.on('data', function (data) {
childProcess.stderr.on('data', function(data) {
spawnErr += data;
});
})
.then(function () {
.then(function() {
assert.equal(spawnOut.toString(), 'hello\n');
assert.equal(spawnErr.toString(), '');
done();
Expand Down Expand Up @@ -441,11 +449,12 @@ describe('child-process-promise', function() {
.then(function(result) {
done(new Error('rejection expected!'));
})
.catch(function(result) {
expect(result.stdout).to.equal('');
expect(result.stderr).to.equal('ERROR');
expect(result.childProcess).to.be.an('object');
expect(result.childProcess).to.equal(childProcess);
.catch(function(error) {
expect(error).to.be.an.instanceof(ChildProcessError);
expect(error.stdout).to.equal('');
expect(error.stderr).to.equal('ERROR');
expect(error.childProcess).to.be.an('object');
expect(error.childProcess).to.equal(childProcess);
done();
})
.done();
Expand All @@ -460,6 +469,8 @@ describe('child-process-promise', function() {
done(new Error('rejection was expected but it completed successfully!'));
})
.catch(function(e) {
expect(e).to.be.an.instanceof(ChildProcessError);
expect(e.code).to.equal(1);
expect(e.toString()).to.contain(missingFilePath);
done();
})
Expand All @@ -475,6 +486,7 @@ describe('child-process-promise', function() {
done(new Error('rejection was expected but it completed successfully!'));
})
.fail(function(e) {
expect(e).to.be.an.instanceof(ChildProcessError);
expect(e.toString()).to.contain(missingFilePath);
done();
})
Expand All @@ -487,14 +499,14 @@ describe('child-process-promise', function() {

var forkSuccessfulReceived = false;

promise.childProcess.on('message', function (message) {
promise.childProcess.on('message', function(message) {
if (message && message.type === 'forkSuccessful') {
forkSuccessfulReceived = true;
}
});

promise
.then(function () {
.then(function() {
assert.equal(forkSuccessfulReceived, true);
done();
})
Expand All @@ -508,14 +520,14 @@ describe('child-process-promise', function() {
var forkSuccessfulReceived = false;

promise
.progress(function (childProcess) {
childProcess.on('message', function (message) {
.progress(function(childProcess) {
childProcess.on('message', function(message) {
if (message && message.type === 'forkSuccessful') {
forkSuccessfulReceived = true;
}
});
})
.then(function () {
.then(function() {
assert.equal(forkSuccessfulReceived, true);
done();
})
Expand Down

0 comments on commit 217609b

Please sign in to comment.