readline: fix pre-aborted signal question handling · nodejs/node@6cc1e15

2 files changed

lines changed

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
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 });