Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
readline: propagate signal.reason in awaitable question
Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: #41008
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
  • Loading branch information
jasnell authored and danielleadams committed Dec 13, 2021
1 parent e795547 commit 67124ac
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 4 deletions.
5 changes: 3 additions & 2 deletions lib/readline.js
Expand Up @@ -157,15 +157,16 @@ Interface.prototype.question[promisify.custom] = function(query, options) {
options = typeof options === 'object' && options !== null ? options : {};

if (options.signal && options.signal.aborted) {
return PromiseReject(new AbortError());
return PromiseReject(
new AbortError(undefined, { cause: options.signal.reason }));
}

return new Promise((resolve, reject) => {
let cb = resolve;

if (options.signal) {
const onAbort = () => {
reject(new AbortError());
reject(new AbortError(undefined, { cause: options.signal.reason }));
};
options.signal.addEventListener('abort', onAbort, { once: true });
cb = (answer) => {
Expand Down
5 changes: 3 additions & 2 deletions lib/readline/promises.js
Expand Up @@ -30,12 +30,13 @@ class Interface extends _Interface {
if (options?.signal) {
validateAbortSignal(options.signal, 'options.signal');
if (options.signal.aborted) {
return reject(new AbortError());
return reject(
new AbortError(undefined, { cause: options.signal.reason }));
}

const onAbort = () => {
this[kQuestionCancel]();
reject(new AbortError());
reject(new AbortError(undefined, { cause: options.signal.reason }));
};
options.signal.addEventListener('abort', onAbort, { once: true });
cb = (answer) => {
Expand Down
9 changes: 9 additions & 0 deletions test/parallel/test-readline-promises-interface.js
Expand Up @@ -910,6 +910,15 @@ for (let i = 0; i < 12; i++) {
rli.close();
}

(async () => {
const [rli] = getInterface({ terminal });
const signal = AbortSignal.abort('boom');
await assert.rejects(rli.question('hello', { signal }), {
cause: 'boom',
});
rli.close();
})().then(common.mustCall());

// Throw an error when question is executed with an aborted signal
{
const ac = new AbortController();
Expand Down

0 comments on commit 67124ac

Please sign in to comment.