Skip to content

repl: catch promise errors during eval in completion #58943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

islandryu
Copy link
Member

Fixes: #58903
The issue occurred when an unhandled Promise was executed during the completion's eval.

This change catches and ignores the error, similar to the handling here.

node/lib/repl.js

Line 1544 in 6a3b545

const evalExpr = `try { ${expr} } catch {}`;

@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 Jul 3, 2025
Copy link

codecov bot commented Jul 3, 2025

Codecov Report

Attention: Patch coverage is 66.66667% with 3 lines in your changes missing coverage. Please review.

Project coverage is 90.04%. Comparing base (09b4c57) to head (7b2d30c).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
lib/repl.js 66.66% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #58943      +/-   ##
==========================================
- Coverage   90.07%   90.04%   -0.04%     
==========================================
  Files         641      641              
  Lines      188998   189007       +9     
  Branches    37069    37079      +10     
==========================================
- Hits       170246   170192      -54     
- Misses      11462    11515      +53     
- Partials     7290     7300      +10     
Files with missing lines Coverage Δ
lib/repl.js 94.09% <66.66%> (-0.12%) ⬇️

... and 28 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.

Copy link
Member

@dario-piotrowicz dario-piotrowicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix itself looks good to me, however I feel like the tests could be improved

{ send: `async function f() {}; f().` },
];

const tests = [
Copy link
Member

@dario-piotrowicz dario-piotrowicz Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are there non-completion tests here?

If these tests are necessary I would suggest to have them in their own separate test file, I don't think there's any benefit in running both set of tests here, is there?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had originally added it just to be safe, even though I knew it wouldn't have any real effect.
But since it’s not strictly necessary, I’ve removed it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can add it as a separate test file, as I had a quick look and I feel like promise evaluation is not being tested? anyways that can be also done separately if we want I think 🙂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, I'll keep it as well in a separate file.
Is it okay to include that in this PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, I'll keep it as well in a separate file.

yeah sounds good to me 🙂

Is it okay to include that in this PR?

Of course 🙂

If you're up for it I think it would be great if you could rebase and have two commits here, one for the tab-complete and one for the new eval tests then we can commit-queue-rebase and have the two clean commits in, I think that that would be the cleanest way to land this 🙂 , but if you don't feel like it the current merge squash is completely fine too 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve rebased the branch!

await runReplTests(tests);
})().then(common.mustCall());

async function runReplCompleteTests(tests) {
Copy link
Member

@dario-piotrowicz dario-piotrowicz Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion tab completion tests should use the repl's complete function as I think that it is the cleanest most robust/stable way for testing this functionality (no need to collect the repl output and add setTimeouts).

For example you can see here: https://github.com/dario-piotrowicz/node/blob/34f24960fb813609f3bd0080ac26bbee1611f142/test/parallel/test-repl-tab-complete-computed-props.js how I recently did it

You can also notice in my tests that the strategy allows to use a single repl instance (since anyways the tests don't rely on state) instead of creating a new one every time

Copy link
Member Author

@islandryu islandryu Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Your approach definitely makes things much simpler.
I've updated the tests to use repl.complete, and also renamed the file accordingly to reflect the change.

Copy link
Member

@dario-piotrowicz dario-piotrowicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks for the updates @islandryu 🫶

@dario-piotrowicz dario-piotrowicz added the commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. label Jul 8, 2025
@islandryu islandryu added commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. and removed commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Jul 9, 2025
@nodejs-github-bot
Copy link
Collaborator

@islandryu
Copy link
Member Author

islandryu commented Jul 10, 2025

@dario-piotrowicz
Could you take another look? I’ve updated the commit.
I only resolved conflicts with the main branch.

@nodejs-github-bot
Copy link
Collaborator

Copy link
Member

@dario-piotrowicz dario-piotrowicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dario-piotrowicz Could you take another look? I’ve updated the commit. I only resolved conflicts with the main branch.

Hi @islandryu 👋

Sorry about the merge conflicts those were my fault 🙇

The changes still look good to me 😄

However now there's an extra eval that I think should also include your check:

node/lib/repl.js

Line 1822 in 7b2d30c

`try { ${exprStr} } catch {} `, ctx, getREPLResourceName(), (err, obj) => {

If you could also add the check there (alongside a test if it's not too problematic) that'd be great 😄

But if you want I can also do that in a separate PR, up to you 🙂

@islandryu
Copy link
Member Author

Thanks for pointing that out!
I'll go ahead and add the check and a test for that part as well.
I’ll probably be able to take a look over the weekend

@islandryu
Copy link
Member Author

#59044
There is a conflict, so I will address it after finishing this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. needs-ci PRs that need a full CI run. repl Issues and PRs related to the REPL subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Promise.reject() hint cause endless loop
4 participants