Skip to content

Commit 35d1def

Browse files
debadree25MoLow
authored andcommitted
child_process: use signal.reason in child process abort
Fixes: #47814 PR-URL: #47817 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com>
1 parent 33daa89 commit 35d1def

4 files changed

Lines changed: 162 additions & 6 deletions

‎lib/child_process.js‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,12 +712,12 @@ function normalizeSpawnArguments(file, args, options) {
712712
};
713713
}
714714

715-
functionabortChildProcess(child,killSignal){
715+
functionabortChildProcess(child,killSignal,reason){
716716
if(!child)
717717
return;
718718
try{
719719
if(child.kill(killSignal)){
720-
child.emit('error',newAbortError());
720+
child.emit('error',newAbortError(undefined,{cause: reason}));
721721
}
722722
}catch(err){
723723
child.emit('error',err);
@@ -787,7 +787,7 @@ function spawn(file, args, options) {
787787
}
788788

789789
functiononAbortListener(){
790-
abortChildProcess(child,killSignal);
790+
abortChildProcess(child,killSignal,options.signal.reason);
791791
}
792792
}
793793

‎test/parallel/test-child-process-exec-abortcontroller-promisified.js‎

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,36 @@ const waitCommand = common.isWindows ?
1818
constac=newAbortController();
1919
constsignal=ac.signal;
2020
constpromise=execPromisifed(waitCommand,{ signal });
21-
assert.rejects(promise,/AbortError/,'post aborted sync signal failed')
22-
.then(common.mustCall());
21+
assert.rejects(promise,{
22+
name: 'AbortError',
23+
cause: newDOMException('This operation was aborted','AbortError'),
24+
}).then(common.mustCall());
2325
ac.abort();
2426
}
2527

28+
{
29+
consterr=newError('boom');
30+
constac=newAbortController();
31+
constsignal=ac.signal;
32+
constpromise=execPromisifed(waitCommand,{ signal });
33+
assert.rejects(promise,{
34+
name: 'AbortError',
35+
cause: err
36+
}).then(common.mustCall());
37+
ac.abort(err);
38+
}
39+
40+
{
41+
constac=newAbortController();
42+
constsignal=ac.signal;
43+
constpromise=execPromisifed(waitCommand,{ signal });
44+
assert.rejects(promise,{
45+
name: 'AbortError',
46+
cause: 'boom'
47+
}).then(common.mustCall());
48+
ac.abort('boom');
49+
}
50+
2651
{
2752
assert.throws(()=>{
2853
execPromisifed(waitCommand,{signal: {}});
@@ -40,6 +65,23 @@ const waitCommand = common.isWindows ?
4065
constsignal=AbortSignal.abort();// Abort in advance
4166
constpromise=execPromisifed(waitCommand,{ signal });
4267

43-
assert.rejects(promise,/AbortError/,'pre aborted signal failed')
68+
assert.rejects(promise,{name: 'AbortError'})
69+
.then(common.mustCall());
70+
}
71+
72+
{
73+
consterr=newError('boom');
74+
constsignal=AbortSignal.abort(err);// Abort in advance
75+
constpromise=execPromisifed(waitCommand,{ signal });
76+
77+
assert.rejects(promise,{name: 'AbortError',cause: err})
78+
.then(common.mustCall());
79+
}
80+
81+
{
82+
constsignal=AbortSignal.abort('boom');// Abort in advance
83+
constpromise=execPromisifed(waitCommand,{ signal });
84+
85+
assert.rejects(promise,{name: 'AbortError',cause: 'boom'})
4486
.then(common.mustCall());
4587
}

‎test/parallel/test-child-process-fork-abort-signal.js‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,26 @@ const { fork } = require('child_process');
2121
}));
2222
process.nextTick(()=>ac.abort());
2323
}
24+
25+
{
26+
// Test aborting with custom error
27+
constac=newAbortController();
28+
const{ signal }=ac;
29+
constcp=fork(fixtures.path('child-process-stay-alive-forever.js'),{
30+
signal
31+
});
32+
cp.on('exit',mustCall((code,killSignal)=>{
33+
strictEqual(code,null);
34+
strictEqual(killSignal,'SIGTERM');
35+
}));
36+
cp.on('error',mustCall((err)=>{
37+
strictEqual(err.name,'AbortError');
38+
strictEqual(err.cause.name,'Error');
39+
strictEqual(err.cause.message,'boom');
40+
}));
41+
process.nextTick(()=>ac.abort(newError('boom')));
42+
}
43+
2444
{
2545
// Test passing an already aborted signal to a forked child_process
2646
constsignal=AbortSignal.abort();
@@ -36,6 +56,23 @@ const { fork } = require('child_process');
3656
}));
3757
}
3858

59+
{
60+
// Test passing an aborted signal with custom error to a forked child_process
61+
constsignal=AbortSignal.abort(newError('boom'));
62+
constcp=fork(fixtures.path('child-process-stay-alive-forever.js'),{
63+
signal
64+
});
65+
cp.on('exit',mustCall((code,killSignal)=>{
66+
strictEqual(code,null);
67+
strictEqual(killSignal,'SIGTERM');
68+
}));
69+
cp.on('error',mustCall((err)=>{
70+
strictEqual(err.name,'AbortError');
71+
strictEqual(err.cause.name,'Error');
72+
strictEqual(err.cause.message,'boom');
73+
}));
74+
}
75+
3976
{
4077
// Test passing a different kill signal
4178
constsignal=AbortSignal.abort();

‎test/parallel/test-child-process-spawn-controller.js‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,48 @@ const aliveScript = fixtures.path('child-process-stay-alive-forever.js');
2727
controller.abort();
2828
}
2929

30+
{
31+
// Verify that passing an AbortSignal with custom abort error works
32+
constcontroller=newAbortController();
33+
const{ signal }=controller;
34+
constcp=spawn(process.execPath,[aliveScript],{
35+
signal,
36+
});
37+
38+
cp.on('exit',common.mustCall((code,killSignal)=>{
39+
assert.strictEqual(code,null);
40+
assert.strictEqual(killSignal,'SIGTERM');
41+
}));
42+
43+
cp.on('error',common.mustCall((e)=>{
44+
assert.strictEqual(e.name,'AbortError');
45+
assert.strictEqual(e.cause.name,'Error');
46+
assert.strictEqual(e.cause.message,'boom');
47+
}));
48+
49+
controller.abort(newError('boom'));
50+
}
51+
52+
{
53+
constcontroller=newAbortController();
54+
const{ signal }=controller;
55+
constcp=spawn(process.execPath,[aliveScript],{
56+
signal,
57+
});
58+
59+
cp.on('exit',common.mustCall((code,killSignal)=>{
60+
assert.strictEqual(code,null);
61+
assert.strictEqual(killSignal,'SIGTERM');
62+
}));
63+
64+
cp.on('error',common.mustCall((e)=>{
65+
assert.strictEqual(e.name,'AbortError');
66+
assert.strictEqual(e.cause,'boom');
67+
}));
68+
69+
controller.abort('boom');
70+
}
71+
3072
{
3173
// Verify that passing an already-aborted signal works.
3274
constsignal=AbortSignal.abort();
@@ -44,6 +86,41 @@ const aliveScript = fixtures.path('child-process-stay-alive-forever.js');
4486
}));
4587
}
4688

89+
{
90+
// Verify that passing an already-aborted signal with custom abort error
91+
// works.
92+
constsignal=AbortSignal.abort(newError('boom'));
93+
constcp=spawn(process.execPath,[aliveScript],{
94+
signal,
95+
});
96+
cp.on('exit',common.mustCall((code,killSignal)=>{
97+
assert.strictEqual(code,null);
98+
assert.strictEqual(killSignal,'SIGTERM');
99+
}));
100+
101+
cp.on('error',common.mustCall((e)=>{
102+
assert.strictEqual(e.name,'AbortError');
103+
assert.strictEqual(e.cause.name,'Error');
104+
assert.strictEqual(e.cause.message,'boom');
105+
}));
106+
}
107+
108+
{
109+
constsignal=AbortSignal.abort('boom');
110+
constcp=spawn(process.execPath,[aliveScript],{
111+
signal,
112+
});
113+
cp.on('exit',common.mustCall((code,killSignal)=>{
114+
assert.strictEqual(code,null);
115+
assert.strictEqual(killSignal,'SIGTERM');
116+
}));
117+
118+
cp.on('error',common.mustCall((e)=>{
119+
assert.strictEqual(e.name,'AbortError');
120+
assert.strictEqual(e.cause,'boom');
121+
}));
122+
}
123+
47124
{
48125
// Verify that waiting a bit and closing works
49126
constcontroller=newAbortController();

0 commit comments

Comments
 (0)