Skip to content

Commit 6cc1e15

Browse files
LinkgoronMylesBorins
authored andcommitted
readline: fix pre-aborted signal question handling
fix pre-aborted question handling PR-URL: #37929 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent a1123f0 commit 6cc1e15

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

lib/readline.js

+9
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const {
5959
StringPrototypeStartsWith,
6060
StringPrototypeTrim,
6161
Promise,
62+
PromiseReject,
6263
Symbol,
6364
SymbolAsyncIterator,
6465
SafeStringIterator,
@@ -385,6 +386,10 @@ Interface.prototype.question = function(query, options, cb) {
385386
options = typeof options === 'object' && options !== null ? options : {};
386387

387388
if (options.signal) {
389+
if (options.signal.aborted) {
390+
return;
391+
}
392+
388393
options.signal.addEventListener('abort', () => {
389394
this[kQuestionCancel]();
390395
}, { once: true });
@@ -405,6 +410,10 @@ Interface.prototype.question = function(query, options, cb) {
405410
Interface.prototype.question[promisify.custom] = function(query, options) {
406411
options = typeof options === 'object' && options !== null ? options : {};
407412

413+
if (options.signal && options.signal.aborted) {
414+
return PromiseReject(new AbortError());
415+
}
416+
408417
return new Promise((resolve, reject) => {
409418
this.question(query, options, resolve);
410419

test/parallel/test-readline-interface.js

+25
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,31 @@ for (let i = 0; i < 12; i++) {
968968
rli.close();
969969
}
970970

971+
// pre-aborted signal
972+
{
973+
const signal = AbortSignal.abort();
974+
const [rli] = getInterface({ terminal });
975+
rli.pause();
976+
rli.on('resume', common.mustNotCall());
977+
rli.question('hello?', { signal }, common.mustNotCall());
978+
rli.close();
979+
}
980+
981+
// pre-aborted signal promisified question
982+
{
983+
const signal = AbortSignal.abort();
984+
const [rli] = getInterface({ terminal });
985+
const question = util.promisify(rli.question).bind(rli);
986+
rli.on('resume', common.mustNotCall());
987+
rli.pause();
988+
question('hello?', { signal })
989+
.then(common.mustNotCall())
990+
.catch(common.mustCall((error) => {
991+
assert.strictEqual(error.name, 'AbortError');
992+
}));
993+
rli.close();
994+
}
995+
971996
// Can create a new readline Interface with a null output argument
972997
{
973998
const [rli, fi] = getInterface({ output: null, terminal });

0 commit comments

Comments
 (0)