Skip to content

Commit efe19b5

Browse files
dario-piotrowicztargos
authored andcommitted
repl: fix eval errors thrown after close throwing ERR_USE_AFTER_CLOSE
prevent incorrect throws of `ERR_USE_AFTER_CLOSE` errors when the eval function of a repl server returns an error after the repl server has been closed PR-URL: #58791 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent d07ce8e commit efe19b5

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

lib/repl.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,9 @@ function REPLServer(prompt,
748748
process.emit('uncaughtException', e);
749749
self.clearBufferedCommand();
750750
self.lines.level = [];
751-
self.displayPrompt();
751+
if (!self.closed) {
752+
self.displayPrompt();
753+
}
752754
});
753755
} else {
754756
if (errStack === '') {
@@ -778,7 +780,9 @@ function REPLServer(prompt,
778780
self.output.write(errStack);
779781
self.clearBufferedCommand();
780782
self.lines.level = [];
781-
self.displayPrompt();
783+
if (!self.closed) {
784+
self.displayPrompt();
785+
}
782786
}
783787
});
784788

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const repl = require('node:repl');
5+
const stream = require('node:stream');
6+
const assert = require('node:assert');
7+
8+
// This test checks that an eval function returning an error in its callback
9+
// after the repl server has been closed doesn't cause an ERR_USE_AFTER_CLOSE
10+
// error to be thrown (reference: https://github.com/nodejs/node/issues/58784)
11+
12+
(async () => {
13+
const close$ = Promise.withResolvers();
14+
const eval$ = Promise.withResolvers();
15+
16+
const input = new stream.PassThrough();
17+
const output = new stream.PassThrough();
18+
19+
const replServer = repl.start({
20+
input,
21+
output,
22+
eval(_cmd, _context, _file, cb) {
23+
close$.promise.then(() => {
24+
cb(new Error('Error returned from the eval callback'));
25+
eval$.resolve();
26+
});
27+
},
28+
});
29+
30+
let outputStr = '';
31+
output.on('data', (data) => {
32+
outputStr += data;
33+
});
34+
35+
input.write('\n');
36+
37+
replServer.close();
38+
close$.resolve();
39+
40+
process.on('uncaughtException', common.mustNotCall());
41+
42+
await eval$.promise;
43+
44+
assert.match(outputStr, /Uncaught Error: Error returned from the eval callback/);
45+
})().then(common.mustCall());

0 commit comments

Comments
 (0)