Skip to content

Commit 60b2754

Browse files
committed
repl: catch promise errors during eval in completion
Fixes: #58903
1 parent 8b199ee commit 60b2754

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

lib/repl.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ const {
9898

9999
const {
100100
isProxy,
101+
isPromise,
101102
} = require('internal/util/types');
102103

103104
const { BuiltinModule } = require('internal/bootstrap/realm');
@@ -1544,6 +1545,10 @@ function complete(line, callback) {
15441545
const evalExpr = `try { ${expr} } catch {}`;
15451546
this.eval(evalExpr, this.context, getREPLResourceName(), (e, obj) => {
15461547
try {
1548+
if (isPromise(obj)) {
1549+
obj.catch(() => {});
1550+
}
1551+
15471552
let p;
15481553
if ((typeof obj === 'object' && obj !== null) ||
15491554
typeof obj === 'function') {
@@ -1733,6 +1738,9 @@ function includesProxiesOrGetters(exprSegments, evalFn, context, callback, curre
17331738
const currentSegment = exprSegments[idx];
17341739
currentExpr += `${currentExpr.length === 0 ? '' : '.'}${currentSegment}`;
17351740
evalFn(`try { ${currentExpr} } catch { }`, context, getREPLResourceName(), (_, currentObj) => {
1741+
if (isPromise(currentObj)) {
1742+
currentObj.catch(() => {});
1743+
}
17361744
if (typeof currentObj !== 'object' || currentObj === null) {
17371745
return callback(false);
17381746
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const repl = require('repl');
5+
const ArrayStream = require('../common/arraystream');
6+
const assert = require('assert');
7+
8+
const completionTests = [
9+
{ send: 'Promise.reject().' },
10+
{ send: 'let p = Promise.reject().' },
11+
{ send: 'Promise.resolve().' },
12+
{ send: 'Promise.resolve().then(() => {}).' },
13+
{ send: `async function f() {throw new Error('test');}; f().` },
14+
{ send: `async function f() {}; f().` },
15+
];
16+
17+
(async function() {
18+
await runReplCompleteTests(completionTests);
19+
})().then(common.mustCall());
20+
21+
async function runReplCompleteTests(tests) {
22+
const input = new ArrayStream();
23+
const output = new ArrayStream();
24+
25+
const replServer = repl.start({
26+
prompt: '',
27+
input,
28+
output: output,
29+
allowBlockingCompletions: true,
30+
terminal: true
31+
});
32+
33+
replServer._domain.on('error', (e) => {
34+
assert.fail(`Error in REPL domain: ${e}`);
35+
});
36+
for (const { send } of tests) {
37+
replServer.complete(
38+
send,
39+
common.mustCall((error, data) => {
40+
assert.strictEqual(error, null);
41+
assert.strictEqual(data.length, 2);
42+
assert.strictEqual(typeof data[1], 'string');
43+
assert.ok(send.includes(data[1]));
44+
})
45+
);
46+
}
47+
}

0 commit comments

Comments
 (0)