Skip to content

Conversation

@mcollina
Copy link
Member

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

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. repl Issues and PRs related to the REPL subsystem. labels Dec 30, 2025
@avivkeller avivkeller added the semver-major PRs that contain breaking changes and should be released in the next major version. label Jan 1, 2026
mcollina added a commit to mcollina/node that referenced this pull request Jan 10, 2026
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: nodejs#61227
@mcollina mcollina force-pushed the repl/remove-domain-dependency branch from 6ef82e6 to e86555a Compare January 10, 2026 10:35
@mcollina mcollina marked this pull request as ready for review January 10, 2026 10:35
@codecov
Copy link

codecov bot commented Jan 10, 2026

Codecov Report

❌ Patch coverage is 88.60104% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.54%. Comparing base (4f24aff) to head (855468d).
⚠️ Report is 122 commits behind head on main.

Files with missing lines Patch % Lines
lib/repl.js 88.60% 22 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #61227      +/-   ##
==========================================
+ Coverage   88.53%   88.54%   +0.01%     
==========================================
  Files         703      704       +1     
  Lines      208546   208781     +235     
  Branches    40217    40282      +65     
==========================================
+ Hits       184634   184867     +233     
+ Misses      15926    15924       -2     
- Partials     7986     7990       +4     
Files with missing lines Coverage Δ
lib/repl.js 93.13% <88.60%> (-0.99%) ⬇️

... and 76 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mcollina
Copy link
Member Author

@nodejs/tsc this needs more reviews

@aduh95
Copy link
Contributor

aduh95 commented Jan 10, 2026

There are linter and test failures to address

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: nodejs#61227
@mcollina mcollina force-pushed the repl/remove-domain-dependency branch from e86555a to 855468d Compare January 11, 2026 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. repl Issues and PRs related to the REPL subsystem. semver-major PRs that contain breaking changes and should be released in the next major version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants