You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ra...@apache.org on 2019/04/01 14:47:31 UTC
[cordova-common] branch master updated: Catch leaked exceptions in
superspawn and convert them to rejections
This is an automated email from the ASF dual-hosted git repository.
raphinesse pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-common.git
The following commit(s) were added to refs/heads/master by this push:
new 469e7b4 Catch leaked exceptions in superspawn and convert them to rejections
469e7b4 is described below
commit 469e7b4a49a1a39c7fc22aa206730b9d58613467
Author: Raphael von der GrĂ¼n <ra...@gmail.com>
AuthorDate: Mon Apr 1 16:47:27 2019 +0200
Catch leaked exceptions in superspawn and convert them to rejections
At least until Node.js 8, child_process.spawn will throw exceptions
instead of emitting error events in certain cases (like EACCES), Thus we
have to wrap the execution in try/catch to convert them into rejections.
---
spec/superspawn.spec.js | 19 +++++++++++++++++++
src/superspawn.js | 16 +++++++++++++---
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/spec/superspawn.spec.js b/spec/superspawn.spec.js
index 95056dc..9c05129 100644
--- a/spec/superspawn.spec.js
+++ b/spec/superspawn.spec.js
@@ -89,6 +89,25 @@ describe('spawn method', function () {
});
});
+ it('Test 005 : should not throw but reject', () => {
+ if (process.platform === 'win32') {
+ pending('Test should not run on Windows');
+ }
+
+ // Our non-executable (as in no execute permission) script
+ const TEST_SCRIPT = path.join(__dirname, 'fixtures/echo-args.cmd');
+
+ let promise;
+ expect(() => { promise = superspawn.spawn(TEST_SCRIPT, []); }).not.toThrow();
+
+ return Promise.resolve(promise).then(_ => {
+ fail('Expected promise to be rejected');
+ }, err => {
+ expect(err).toEqual(jasmine.any(Error));
+ expect(err.code).toBe('EACCES');
+ });
+ });
+
describe('operation on windows', () => {
const TEST_SCRIPT = path.join(__dirname, 'fixtures/echo-args.cmd');
const TEST_ARGS = [ 'install', 'foo@^1.2.3', 'c o r d o v a' ];
diff --git a/src/superspawn.js b/src/superspawn.js
index 22daf88..2e58b2e 100644
--- a/src/superspawn.js
+++ b/src/superspawn.js
@@ -87,7 +87,15 @@ exports.spawn = function (cmd, args, opts) {
events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + cmd + ' ' + args.join(' '));
- var child = crossSpawn.spawn(cmd, args, spawnOpts);
+ // At least until Node.js 8, child_process.spawn will throw exceptions
+ // instead of emitting error events in certain cases (like EACCES), Thus we
+ // have to wrap the execution in try/catch to convert them into rejections.
+ try {
+ var child = crossSpawn.spawn(cmd, args, spawnOpts);
+ } catch (e) {
+ whenDone(e);
+ return d.promise;
+ }
var capturedOut = '';
var capturedErr = '';
@@ -110,8 +118,10 @@ exports.spawn = function (cmd, args, opts) {
child.on('close', whenDone);
child.on('error', whenDone);
function whenDone (arg) {
- child.removeListener('close', whenDone);
- child.removeListener('error', whenDone);
+ if (child) {
+ child.removeListener('close', whenDone);
+ child.removeListener('error', whenDone);
+ }
var code = typeof arg === 'number' ? arg : arg && arg.code;
events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org