Skip to content

Commit 1f36262

Browse files
committed
child_process: Pass child in resolve/reject too
1 parent 66810a0 commit 1f36262

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

doc/api/child_process.md

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ encoding, `Buffer` objects will be passed to the callback instead.
209209
const { exec } = require('child_process');
210210
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
211211
if (error) {
212-
console.error(`exec error: ${error}`);
213-
return;
212+
console.error(`exit(${error.code}): ${error}`);
214213
}
215214
console.log(`stdout: ${stdout}`);
216215
console.error(`stderr: ${stderr}`);
@@ -224,6 +223,8 @@ child runs longer than `timeout` milliseconds.
224223
Unlike the exec(3) POSIX system call, `child_process.exec()` does not replace
225224
the existing process and uses a shell to execute the command.
226225

226+
#### exec with promisify
227+
227228
If this method is invoked as its [`util.promisify()`][]ed version, it returns
228229
a `Promise` for an `Object` with `stdout` and `stderr` properties. The returned
229230
`ChildProcess` instance is attached to the `Promise` as a `child` property. In
@@ -306,19 +307,34 @@ can be used to specify the character encoding used to decode the stdout and
306307
stderr output. If `encoding` is `'buffer'`, or an unrecognized character
307308
encoding, `Buffer` objects will be passed to the callback instead.
308309

310+
#### execFile with promisify
311+
309312
If this method is invoked as its [`util.promisify()`][]ed version, it returns
310-
a `Promise` for an `Object` with `stdout` and `stderr` properties. The returned
311-
`ChildProcess` instance is attached to the `Promise` as a `child` property. In
312-
case of an error (including any error resulting in an exit code other than 0), a
313-
rejected promise is returned, with the same `error` object given in the
314-
callback, but with two additional properties `stdout` and `stderr`.
313+
a `Promise`, with an additional property `child` with the `ChildProcess` that
314+
would normally be returned by `execFile`.
315+
316+
On a successful exit (a zero status code), the promise resolves to an object
317+
with `child`, `stdout`, and `stderr` properties.
318+
319+
On an unsuccessful exit, the promise resolves to the same `error` returned in
320+
the callback, with three additional properties `child`, `stdout`, `stderr`,
321+
which provide the output of the process. As with `exec`, the exit code is
322+
attached to the `code` property.
315323

316324
```js
317-
const util = require('util');
318-
const execFile = util.promisify(require('child_process').execFile);
325+
const { promisify } = require('util');
326+
const execFile = promisify(require('child_process').execFile);
319327
async function getVersion() {
320-
const { stdout } = await execFile('node', ['--version']);
321-
console.log(stdout);
328+
try {
329+
const { stdout, stderr, child } = await execFile('node', ['--version']);
330+
console.log(`pid ${child.pid} exit`);
331+
console.log(`stdout: ${stdout}`);
332+
console.error(`stderr: ${stderr}`);
333+
} catch (error) {
334+
console.error(`pid ${error.child.pid} exit(${error.code}): ${error}`);
335+
console.log(`stdout: ${error.stdout}`);
336+
console.error(`stderr: ${error.stderr}`);
337+
}
322338
}
323339
getVersion();
324340
```

lib/child_process.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,14 @@ const customPromiseExecFunction = (orig) => {
169169
reject = rej;
170170
});
171171

172-
promise.child = orig(...args, (err, stdout, stderr) => {
172+
const child = promise.child = orig(...args, (err, stdout, stderr) => {
173173
if (err !== null) {
174+
err.child = child;
174175
err.stdout = stdout;
175176
err.stderr = stderr;
176177
reject(err);
177178
} else {
178-
resolve({ stdout, stderr });
179+
resolve({ child, stdout, stderr });
179180
}
180181
});
181182

test/parallel/test-child-process-promisified.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ const execFile = promisify(child_process.execFile);
1212

1313
assert(promise.child instanceof child_process.ChildProcess);
1414
promise.then(common.mustCall((obj) => {
15-
assert.deepStrictEqual(obj, { stdout: '42\n', stderr: '' });
15+
assert(obj.child instanceof child_process.ChildProcess);
16+
assert.strictEqual(obj.stdout, '42\n');
17+
assert.strictEqual(obj.stderr, '');
1618
}));
1719
}
1820

@@ -21,7 +23,9 @@ const execFile = promisify(child_process.execFile);
2123

2224
assert(promise.child instanceof child_process.ChildProcess);
2325
promise.then(common.mustCall((obj) => {
24-
assert.deepStrictEqual(obj, { stdout: '42\n', stderr: '' });
26+
assert(obj.child instanceof child_process.ChildProcess);
27+
assert.strictEqual(obj.stdout, '42\n');
28+
assert.strictEqual(obj.stderr, '');
2529
}));
2630
}
2731

@@ -31,6 +35,7 @@ const execFile = promisify(child_process.execFile);
3135
assert(promise.child instanceof child_process.ChildProcess);
3236
promise.catch(common.mustCall((err) => {
3337
assert(err.message.includes('doesntexist'));
38+
assert(err.child instanceof child_process.ChildProcess);
3439
}));
3540
}
3641

@@ -40,13 +45,15 @@ const execFile = promisify(child_process.execFile);
4045
assert(promise.child instanceof child_process.ChildProcess);
4146
promise.catch(common.mustCall((err) => {
4247
assert(err.message.includes('doesntexist'));
48+
assert(err.child instanceof child_process.ChildProcess);
4349
}));
4450
}
4551
const failingCodeWithStdoutErr =
4652
'console.log(42);console.error(43);process.exit(1)';
4753
{
4854
exec(`${process.execPath} -e "${failingCodeWithStdoutErr}"`)
4955
.catch(common.mustCall((err) => {
56+
assert(err.child instanceof child_process.ChildProcess);
5057
assert.strictEqual(err.code, 1);
5158
assert.strictEqual(err.stdout, '42\n');
5259
assert.strictEqual(err.stderr, '43\n');
@@ -56,6 +63,7 @@ const failingCodeWithStdoutErr =
5663
{
5764
execFile(process.execPath, ['-e', failingCodeWithStdoutErr])
5865
.catch(common.mustCall((err) => {
66+
assert(err.child instanceof child_process.ChildProcess);
5967
assert.strictEqual(err.code, 1);
6068
assert.strictEqual(err.stdout, '42\n');
6169
assert.strictEqual(err.stderr, '43\n');

0 commit comments

Comments
 (0)