readline: propagate signal.reason in awaitable question

Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: https://github.com/nodejs/node/pull/41008
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
James M Snell 2021-11-28 12:43:49 -08:00
parent a2982798e3
commit 07fbed3d5f
No known key found for this signature in database
GPG Key ID: 7341B15C070877AC
3 changed files with 15 additions and 4 deletions

View File

@ -157,7 +157,8 @@ 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) => {
@ -165,7 +166,7 @@ Interface.prototype.question[promisify.custom] = function(query, options) {
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) => {

View File

@ -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) => {

View File

@ -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();