Replace the domain-based error handling with AsyncLocalStorage and setUncaughtExceptionCaptureCallback. This removes the REPL's dependency on the deprecated domain module while preserving all existing behavior: - Synchronous errors during eval are caught and displayed - Async errors (setTimeout, promises, etc.) are caught via the uncaught exception capture callback - Top-level await errors are caught and displayed - The REPL continues operating after errors - Multiple REPL instances can coexist with errors routed correctly Changes: - Use AsyncLocalStorage to track which REPL instance owns an async context, replacing domain's automatic async tracking - Add setupExceptionCapture() to install setUncaughtExceptionCaptureCallback for catching async errors and routing them to the correct REPL - Extract error handling logic into REPLServer.prototype._handleError() - Wrap eval execution in replContext.run() for async context tracking - Update newListener protection to check AsyncLocalStorage context - Throw ERR_INVALID_ARG_VALUE if options.domain is passed PR-URL: https://github.com/nodejs/node/pull/61227 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
44 lines
No EOL
1.2 KiB
JavaScript
44 lines
No EOL
1.2 KiB
JavaScript
// Tab completion sometimes uses a separate REPL instance under the hood.
|
|
// Make sure errors in completion callbacks are properly thrown.
|
|
//
|
|
// Ref: https://github.com/nodejs/node/issues/21586
|
|
|
|
'use strict';
|
|
|
|
const { Stream } = require('stream');
|
|
function noop() {}
|
|
|
|
// A stream to push an array into a REPL
|
|
function ArrayStream() {
|
|
this.run = function(data) {
|
|
data.forEach((line) => {
|
|
this.emit('data', `${line}\n`);
|
|
});
|
|
};
|
|
}
|
|
|
|
Object.setPrototypeOf(ArrayStream.prototype, Stream.prototype);
|
|
Object.setPrototypeOf(ArrayStream, Stream);
|
|
ArrayStream.prototype.readable = true;
|
|
ArrayStream.prototype.writable = true;
|
|
ArrayStream.prototype.pause = noop;
|
|
ArrayStream.prototype.resume = noop;
|
|
ArrayStream.prototype.write = noop;
|
|
|
|
const repl = require('repl');
|
|
|
|
const putIn = new ArrayStream();
|
|
const testMe = repl.start('', putIn);
|
|
|
|
// Nesting of structures causes REPL to use a nested REPL for completion.
|
|
putIn.run([
|
|
'var top = function() {',
|
|
'r = function test (',
|
|
' one, two) {',
|
|
'var inner = {',
|
|
' one:1',
|
|
'};'
|
|
]);
|
|
|
|
// In Node.js 10.11.0, this next line will terminate the repl silently...
|
|
testMe.complete('inner.o', () => { throw new Error('fhqwhgads'); }); |