-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
module: improve detection try catch #52242
Conversation
…corate the error when not retrying
Review requested:
|
@nodejs/v8 When I run // Next run: With `breakOnUncaught` it only pauses on the 2nd exception.
await cli.command('breakOnUncaught');
await cli.stepCommand('r'); // Also, the setting survives the restart.
await cli.waitForInitialBreak();
assert.deepStrictEqual(cli.breakInfo, { filename: script, line: 1 });
await cli.stepCommand('c');
assert.ok(cli.output.includes(`exception in ${script}:9`)); If I log that
Which should be the fixture code, not Node internal code. I guess that somehow |
const source = cjsLoader.entryPointSource; | ||
|
||
tryCatchRethrow(() => { | ||
// Module._load is the monkey-patchable CJS module loader. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling back from C++ to JS would have a non-trivial performance impact. I think the proper way to deal with this without all the weird error handling should be handling ESM directly in the CJS loader when the compilation fails and the source looks like ESM (and if it's async, simply ignoring the exports of the entry point/making it some kind of dummy object should be fine, because no one really needs that, or if they do weird things like process.mainModule.exports
, we can warn/error when the entry point is async ESM).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a branch here built on top of #52413 that implements the idea above + require(esm)
detection. This moves the reparsing into C++ and also handles ESM entrypoints in-place in the CJS loader (by just doing cascadedLoader.import()
and making the CJS exports a proxy that emits a warning, technically I think we can just delete process.mainModule
in that case, then it would probably be impossible to reach to the exports of the entry point without some hacky monkey patch that maybe no one really does), so it passes ./node test/parallel/test-debugger-exceptions.js
when the flag is flipped because the error doesn't bubble all the way up.
Sorry for not responding any earlier. Two questions I would have is:
But maybe that's moot if the alternate implementation approach that @joyeecheung mentioned shakes out. |
Yes, fortunately I think it's moot now thanks to Joyee's PR. |
This refactors the
try
/catch
added in #52093 to happen in C++, so that the rethrown error preserves the same origin, source arrow and source map-translated stack trace. This gets us much closer to being able to unflag--experimental-detect-module
and have all the tests pass. The C++ was written by @targosThere’s currently only one test failing on this branch, and I’d love some help getting it to pass.
./node test/parallel/test-debugger-exceptions.js
is failing because innode inspect
, for some reason the inspector sees the exception as being thrown by the newTryCatchRethrow
rather than the rethrown exception. If anyone can figure out why this is and what we can do about it, I would be very grateful. cc @jkrems @nodejs/loaders @nodejs/inspector @nodejs/v8-inspector