Skip to content
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

process: add exitWithException() #25715

Closed
wants to merge 1 commit into from

Conversation

Fishrock123
Copy link
Contributor

@Fishrock123 Fishrock123 commented Jan 25, 2019

Adds a public way to access node::FatalException from javascript, as process.exitWithException().

If an error stack is available on the value, this method of exiting does not add additional context, unlike regular re-throwing, yet also uses the regular error printing logic. This behavior is particularly desirable when doing 'fatal exits' from the unhandledRejection event.

... Been wanting this for some months now. 🙃

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@Fishrock123 Fishrock123 added semver-minor PRs that contain new features and should be released in the next minor version. process Issues and PRs related to the process subsystem. labels Jan 25, 2019
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Jan 25, 2019
@Fishrock123

This comment has been minimized.

doc/api/process.md Outdated Show resolved Hide resolved
doc/api/process.md Outdated Show resolved Hide resolved
doc/api/process.md Outdated Show resolved Hide resolved
@addaleax

This comment has been minimized.

doc/api/process.md Outdated Show resolved Hide resolved
@Fishrock123

This comment has been minimized.

@addaleax
Copy link
Member

@Fishrock123 Yeah, I assume the question is which error should take precedence. For this API it might be the most intuitive thing to let the error from the getter bubble back up to JS land, but … that might be hard for the general case, when we might not have a JS stack below the FatalException handler?

@Fishrock123 Fishrock123 force-pushed the process-re-throw branch 2 times, most recently from 6fa69f9 to 5e2415c Compare January 25, 2019 23:31
@Fishrock123
Copy link
Contributor Author

Fishrock123 commented Jan 26, 2019

So, uhhh, considering you can make node SIGABRT with a throw statement... I think we'll lave that for a separate issue.

node -e "throw { get stack() { throw new Error('weird throw but ok') } }"

Edit: fixed in #25834

@BridgeAR
Copy link
Member

BridgeAR commented Mar 5, 2019

@Fishrock123 this needs a rebase

@Fishrock123 Fishrock123 changed the title process: add process.throw() process: add process.triggerFatalException() May 10, 2019
@Fishrock123
Copy link
Contributor Author

Fishrock123 commented May 10, 2019

Rebased and updated this to process.triggerFatalException() from process.throw(). PTAL.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot
Copy link
Collaborator

doc/api/process.md Outdated Show resolved Hide resolved
@joyeecheung
Copy link
Member

joyeecheung commented May 11, 2019

I know the name comes from existing internal methods, but TBH I think it's a bit confusing, since

  1. There is process._fatalException which is called by this
  2. There is v8::Isolate::SetFatalErrorHandler and our handler does something quite different - it prints the C++ stack trace, writes the node report if configured, and then ABORT() the process.

If there is a scale of how fatal something is, 2 feels more "fatal" to me, since at that point there is less stuff that you are allowed to do (e.g. this happens when we use the V8 API incorrectly and there is basically nothing the user can do to recover from that)

Something like exitWithException may be less confusing, and we should mention the exit code behavior - it's kind of tricky with this one, it could be either 6, 7, 1, or process.exitCode, depending on a bunch of conditions. (Also note that process._fatalException is monkey-patchable and there is no clear deprecation for it)

@joyeecheung
Copy link
Member

joyeecheung commented May 11, 2019

Or, maybe we could make this an overload of process.exit(), as the part missing from the current process.exit() is just a call of process._fatalException and a call to ReportException. It also reads more naturally in the unhandledRejection handler as you do not appear to retrigger an exception (which is what it does, the error will not be triggered in the VM again).

@nodejs-github-bot
Copy link
Collaborator

@Fishrock123
Copy link
Contributor Author

Do people think this sort of functionality should attempt to bypass _fatalException altogether?

Copy link
Member

@BridgeAR BridgeAR left a comment

Choose a reason for hiding this comment

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

LGTM with the comments addressed.

doc/api/process.md Outdated Show resolved Hide resolved
@BridgeAR
Copy link
Member

@Fishrock123 I would keep it. That way it's consistent and has the same output as other errors.

@Fishrock123
Copy link
Contributor Author

@joyeecheung LGTY?

lib/internal/bootstrap/node.js Show resolved Hide resolved
src/node_process_methods.cc Outdated Show resolved Hide resolved

As an example:
```js
process.on('unhandledRejection', (err) => {
Copy link
Member

@joyeecheung joyeecheung May 20, 2019

Choose a reason for hiding this comment

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

What happens if this is uncaughtException? I think that results in a dead loop? I think we should at least document about this footgun, but maybe a better solution is to just implement this separately and exclude part of process._fatalException() - or otherwise this does not exit unconditionally any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, throw seems to be short-cut somehow, but this blows the stack size. :/

Copy link
Member

@joyeecheung joyeecheung May 21, 2019

Choose a reason for hiding this comment

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

Are we even supposed to emit 'uncaughtException' when this is called? If so is there any point of using this instead of...well, just throwing an uncaught exception? I can see it makes sense to add this method if it does not trigger 'uncaughtException', but not really if it does..

@Fishrock123 Fishrock123 changed the title process: add process.triggerFatalException() process: add exitWithException() May 21, 2019
Adds a public way to access `node::FatalException` from javascript, as
`process.triggerFatalException()`.

If an error stack is available on the value, this method of exiting
does not add additional context, unlike regular re-throwing, yet also
uses the regular error printing logic. This behavior is particularly
desirable when doing 'fatal exits' from the unhandledRejection event.

PR-URL: nodejs#25715
@fhinkel
Copy link
Member

fhinkel commented Oct 28, 2019

ping @Fishrock123

@Fishrock123
Copy link
Contributor Author

Fishrock123 commented Dec 3, 2019

The problem with this is that internals need to be suitable restructured so as to bypass emitting the 'uncaughtException' event... If it emits 'uncaughtException' you end up with terrible circular execution issues and it's just a mess.

Which probably also means that it need to be renamed, again...

@Fishrock123
Copy link
Contributor Author

It would probably be easier to just expose the exception logger and then call process.exit(1), maybe.

@BridgeAR BridgeAR added the wip Issues and PRs that are still a work in progress. label Dec 20, 2019
@BridgeAR BridgeAR force-pushed the master branch 2 times, most recently from 8ae28ff to 2935f72 Compare May 31, 2020 12:19
@jasnell jasnell added the stalled Issues and PRs that are stalled. label Jun 25, 2020
@jasnell
Copy link
Member

jasnell commented Jun 25, 2020

It is unfortunate that this PR stalled. To move forward, it would need to be rebased and updated and have the uncaughtException recursion figured out. @Fishrock123, I'm going to close the PR but we can reopen if you wish to pick this back up again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. process Issues and PRs related to the process subsystem. semver-minor PRs that contain new features and should be released in the next minor version. stalled Issues and PRs that are stalled. wip Issues and PRs that are still a work in progress.
Projects
None yet
Development

Successfully merging this pull request may close these issues.