child_process: attach child in promisification
This commit updates the custom exec() and execFile() promisification to attach the ChildProcess instance to the returned Promise. PR-URL: https://github.com/nodejs/node/pull/28325 Fixes: https://github.com/nodejs/node/issues/28244 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Wyatt Preul <wpreul@gmail.com>
This commit is contained in:
parent
05359dd0db
commit
3aeb810ca6
@ -214,10 +214,11 @@ Unlike the exec(3) POSIX system call, `child_process.exec()` does not replace
|
|||||||
the existing process and uses a shell to execute the command.
|
the existing process and uses a shell to execute the command.
|
||||||
|
|
||||||
If this method is invoked as its [`util.promisify()`][]ed version, it returns
|
If this method is invoked as its [`util.promisify()`][]ed version, it returns
|
||||||
a `Promise` for an `Object` with `stdout` and `stderr` properties. In case of an
|
a `Promise` for an `Object` with `stdout` and `stderr` properties. The returned
|
||||||
error (including any error resulting in an exit code other than 0), a rejected
|
`ChildProcess` instance is attached to the `Promise` as a `child` property. In
|
||||||
promise is returned, with the same `error` object given in the callback, but
|
case of an error (including any error resulting in an exit code other than 0), a
|
||||||
with an additional two properties `stdout` and `stderr`.
|
rejected promise is returned, with the same `error` object given in the
|
||||||
|
callback, but with an additional two properties `stdout` and `stderr`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
@ -295,9 +296,10 @@ stderr output. If `encoding` is `'buffer'`, or an unrecognized character
|
|||||||
encoding, `Buffer` objects will be passed to the callback instead.
|
encoding, `Buffer` objects will be passed to the callback instead.
|
||||||
|
|
||||||
If this method is invoked as its [`util.promisify()`][]ed version, it returns
|
If this method is invoked as its [`util.promisify()`][]ed version, it returns
|
||||||
a `Promise` for an `Object` with `stdout` and `stderr` properties. In case of an
|
a `Promise` for an `Object` with `stdout` and `stderr` properties. The returned
|
||||||
error (including any error resulting in an exit code other than 0), a rejected
|
`ChildProcess` instance is attached to the `Promise` as a `child` property. In
|
||||||
promise is returned, with the same `error` object given in the
|
case of an error (including any error resulting in an exit code other than 0), a
|
||||||
|
rejected promise is returned, with the same `error` object given in the
|
||||||
callback, but with an additional two properties `stdout` and `stderr`.
|
callback, but with an additional two properties `stdout` and `stderr`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -149,17 +149,24 @@ function exec(command, options, callback) {
|
|||||||
|
|
||||||
const customPromiseExecFunction = (orig) => {
|
const customPromiseExecFunction = (orig) => {
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
return new Promise((resolve, reject) => {
|
let resolve;
|
||||||
orig(...args, (err, stdout, stderr) => {
|
let reject;
|
||||||
if (err !== null) {
|
const promise = new Promise((res, rej) => {
|
||||||
err.stdout = stdout;
|
resolve = res;
|
||||||
err.stderr = stderr;
|
reject = rej;
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve({ stdout, stderr });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
promise.child = orig(...args, (err, stdout, stderr) => {
|
||||||
|
if (err !== null) {
|
||||||
|
err.stdout = stdout;
|
||||||
|
err.stderr = stderr;
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve({ stdout, stderr });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,25 +8,37 @@ const exec = promisify(child_process.exec);
|
|||||||
const execFile = promisify(child_process.execFile);
|
const execFile = promisify(child_process.execFile);
|
||||||
|
|
||||||
{
|
{
|
||||||
exec(`${process.execPath} -p 42`).then(common.mustCall((obj) => {
|
const promise = exec(`${process.execPath} -p 42`);
|
||||||
|
|
||||||
|
assert(promise.child instanceof child_process.ChildProcess);
|
||||||
|
promise.then(common.mustCall((obj) => {
|
||||||
assert.deepStrictEqual(obj, { stdout: '42\n', stderr: '' });
|
assert.deepStrictEqual(obj, { stdout: '42\n', stderr: '' });
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
execFile(process.execPath, ['-p', '42']).then(common.mustCall((obj) => {
|
const promise = execFile(process.execPath, ['-p', '42']);
|
||||||
|
|
||||||
|
assert(promise.child instanceof child_process.ChildProcess);
|
||||||
|
promise.then(common.mustCall((obj) => {
|
||||||
assert.deepStrictEqual(obj, { stdout: '42\n', stderr: '' });
|
assert.deepStrictEqual(obj, { stdout: '42\n', stderr: '' });
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
exec('doesntexist').catch(common.mustCall((err) => {
|
const promise = exec('doesntexist');
|
||||||
|
|
||||||
|
assert(promise.child instanceof child_process.ChildProcess);
|
||||||
|
promise.catch(common.mustCall((err) => {
|
||||||
assert(err.message.includes('doesntexist'));
|
assert(err.message.includes('doesntexist'));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
execFile('doesntexist', ['-p', '42']).catch(common.mustCall((err) => {
|
const promise = execFile('doesntexist', ['-p', '42']);
|
||||||
|
|
||||||
|
assert(promise.child instanceof child_process.ChildProcess);
|
||||||
|
promise.catch(common.mustCall((err) => {
|
||||||
assert(err.message.includes('doesntexist'));
|
assert(err.message.includes('doesntexist'));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user