Skip to content

Commit 611a147

Browse files
DanielVenablemarco-ippolito
authored andcommitted
readline: fix unresolved promise on abortion
Fixes: #53497 PR-URL: #54030 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 043dcdd commit 611a147

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

lib/internal/readline/interface.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ const {
3232
SafeStringIterator,
3333
} = primordials;
3434

35-
const { codes } = require('internal/errors');
36-
3735
const {
38-
ERR_INVALID_ARG_VALUE,
39-
ERR_USE_AFTER_CLOSE,
40-
} = codes;
36+
AbortError,
37+
codes: {
38+
ERR_INVALID_ARG_VALUE,
39+
ERR_USE_AFTER_CLOSE,
40+
},
41+
} = require('internal/errors');
42+
4143
const {
4244
validateAbortSignal,
4345
validateArray,
@@ -111,6 +113,7 @@ const kPrompt = Symbol('_prompt');
111113
const kPushToKillRing = Symbol('_pushToKillRing');
112114
const kPushToUndoStack = Symbol('_pushToUndoStack');
113115
const kQuestionCallback = Symbol('_questionCallback');
116+
const kQuestionReject = Symbol('_questionReject');
114117
const kRedo = Symbol('_redo');
115118
const kRedoStack = Symbol('_redoStack');
116119
const kRefreshLine = Symbol('_refreshLine');
@@ -1126,6 +1129,7 @@ class Interface extends InterfaceConstructor {
11261129
} else {
11271130
// This readline instance is finished
11281131
this.close();
1132+
this[kQuestionReject]?.(new AbortError('Aborted with Ctrl+C'));
11291133
}
11301134
break;
11311135

@@ -1137,6 +1141,7 @@ class Interface extends InterfaceConstructor {
11371141
if (this.cursor === 0 && this.line.length === 0) {
11381142
// This readline instance is finished
11391143
this.close();
1144+
this[kQuestionReject]?.(new AbortError('Aborted with Ctrl+D'));
11401145
} else if (this.cursor < this.line.length) {
11411146
this[kDeleteRight]();
11421147
}
@@ -1392,6 +1397,7 @@ module.exports = {
13921397
kQuestion,
13931398
kQuestionCallback,
13941399
kQuestionCancel,
1400+
kQuestionReject,
13951401
kRefreshLine,
13961402
kSawKeyPress,
13971403
kSawReturnAt,

lib/readline/promises.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
Interface: _Interface,
1313
kQuestion,
1414
kQuestionCancel,
15+
kQuestionReject,
1516
} = require('internal/readline/interface');
1617

1718
const {
@@ -54,6 +55,8 @@ class Interface extends _Interface {
5455
};
5556
}
5657

58+
this[kQuestionReject] = reject;
59+
5760
this[kQuestion](query, cb);
5861
});
5962
}

test/parallel/test-readline-promises-interface.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,22 @@ for (let i = 0; i < 12; i++) {
948948
rli.close();
949949
}
950950

951+
// Aborting a question with ctrl+C
952+
{
953+
const [rli, fi] = getInterface({ terminal: true });
954+
assert.rejects(rli.question('hello?'), { name: 'AbortError' })
955+
.then(common.mustCall());
956+
fi.emit('keypress', '.', { ctrl: true, name: 'c' });
957+
}
958+
959+
// Aborting a question with ctrl+D
960+
{
961+
const [rli, fi] = getInterface({ terminal: true });
962+
assert.rejects(rli.question('hello?'), { name: 'AbortError' })
963+
.then(common.mustCall());
964+
fi.emit('keypress', '.', { ctrl: true, name: 'd' });
965+
}
966+
951967
(async () => {
952968
const [rli] = getInterface({ terminal });
953969
const signal = AbortSignal.abort('boom');

0 commit comments

Comments
 (0)