-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
repl: emit uncaughtException #20803
repl: emit uncaughtException #20803
Conversation
lib/repl.js
Outdated
if (isError && e.stack) { | ||
if (process.listenerCount('uncaughtException') !== 0) { | ||
process.emit('uncaughtException', e); | ||
} else if (isError && e.stack) { |
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 don’t think we want the event being emitted and information being written to stderr to be mutually exclusive? I’d generally expect that the REPL shows global errors that aren’t caught, even if there is an uncaughtException
listener…
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.
Hm, to me it's similar to the "regular" error: if there's no exception listener, the app will crash. In this context it's for me printing to the repl. If the listener is attached, it should only end up there and the user has to decide what to do with it.
This works in the opened To me the hard part is in distinguishing which errors should go to |
Is it actually possible to detect if the |
The question which comes to my mind is whether we should allow one REPL session a look into |
Is there interest in trying to pursue this further? I think it would make sense in case for the opened |
@BridgeAR We do make some customizations for the Node.js main REPL, yes – (Would also be okay with that, yes) |
f962429
to
ca99566
Compare
PTAL I just pushed another commit that limits this functionality strictly to the very first opened repl. In case a second one is opened, it will deactivate the behavior for all. |
@addaleax @apapirovski @AyushG3112 what do you think about the approach? |
Ping @BridgeAR ... what's the status on this? |
ca99566
to
630f80f
Compare
CI https://ci.nodejs.org/job/node-test-pull-request/19139/ PTAL. I guess this is actually getting somewhere. I am just not to sure how to write a test for this. |
@nodejs/repl This could use some reviews. Any takesr? Even someone blocking it would be more useful than it languishing with no approvals and no requests for changes, IMO. |
630f80f
to
f2083ed
Compare
@nodejs/repl @nodejs/tsc PTAL |
@BridgeAR can you post an example repl session that shows the impact of this change? |
f2083ed
to
55be36b
Compare
Yeah, that's fair. I'm having a look myself right now. |
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.
SGTM but is there a way to add a test?
I just reworked some code here due to @apapirovski request for a test because I realized that adding an Therefore I added some more code to fix that behavior as well: it is from now on going to throw an error if the listener is added in such a case. I could theoretically move that part into a separate PR but for me it felt right here. While writing tests I also noticed that the former way of detecting if the REPL was run as standalone program or not was not sufficient. Currently there's no way to detect if it's the internal repl or not, so I added an internal symbol to detect that as well. Therefore I'll ask everyone who had a look at this so far to take another look. Thanks. |
CI https://ci.nodejs.org/job/node-test-pull-request/20347/ @nodejs/tsc PTAL as this is now also fixing a nasty "bug" that could be triggered when using |
Since it's semver-major, should we run CITGM at this time? |
I don’t think we have modules in CITGM that test the default REPL (aka Node’s “interactive” mode) in any way, so I’m not sure it’s worth it? |
Adding an `uncaughtException` listener in an REPL instance suppresses errors in the whole application. Closing the instance won't remove those listeners either.
The internal default repl will from now on trigger `uncaughtException` handlers instead of ignoring them. The regular error output is suppressed in that case.
0c848e1
to
88306b2
Compare
I updated the PR and incorporated the feedback. I also added a PTAL |
Superseded by #27151 I found a way to also handle the async cases properly and this PR changed multiple times, so it felt better to open a new one instead of keeping this one around. |
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 was a little late on the review here. But I will submit it anyway. It's been sitting unsubmitted in my browser for a couple of days.
<a id="ERR_INVALID_REPL_INPUT"></a> | ||
### ERR_INVALID_REPL_INPUT | ||
|
||
The input can or may not be used in the [`REPL`][]. All prohibited inputs are |
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 don't understand what is meant by "can or may not be used".
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 thought I'll keep it broad so that it could be used for different REPL input. So far it will only be used for uncaught exception listeners, so only the may
part applies. I am happy to change it to only may
or what ever you have as alternative.
* Uncaught exceptions do not emit the [`'uncaughtException'`][] event. | ||
* Uncaught exceptions only emit the [`'uncaughtException'`][] event if the | ||
`repl` is used as standalone program. If the `repl` is included anywhere in | ||
another application, adding this event synchronous will throw an |
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.
What is meant by "adding this event synchronous"?
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.
This is actually outdated in the other PR. In this version I was not able to actually handle listeners that were added asynchronously. E.g., setTimeout(() => process.on("uncaughtException", () => {}))
was not detected here. This is fixed in the latest implementation.
|
||
```js | ||
process.on('uncaughtException', () => console.log('Uncaught')); | ||
// TypeError [ERR_INVALID_REPL_INPUT]: Unhandled exception listeners can not be |
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.
Nit: perhaps "Listeners for uncaughtException
cannot be used in the REPL" is a bit clearer.
@@ -40,8 +39,6 @@ process.on('uncaughtException', (e) => { | |||
throw e; | |||
}); | |||
|
|||
process.on('exit', () => (Error.prepareStackTrace = origPrepareStackTrace)); |
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.
This seems unrelated to the PR changes. What am I missing?
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.
It is somewhat unrelated. In a former PR this test was impacted as well and I noticed that this is actually not necessary, so I just went ahead and removed it.
This was just a rough idea after looking into #19998.
I have no real opinion if this is a good idea or not and thought it might be good if others give their opinion. This way it seems like we would be able to actually report
uncaughtException
if a listener is attached.If this is indeed something should could do, I'll also add tests.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes