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

Use our own NonFatal exception classifier #4254

Open
armanbilge opened this issue Jan 23, 2025 · 5 comments · May be fixed by #4263
Open

Use our own NonFatal exception classifier #4254

armanbilge opened this issue Jan 23, 2025 · 5 comments · May be fixed by #4263

Comments

@armanbilge
Copy link
Member

armanbilge commented Jan 23, 2025

In #4247 (comment) I was caught by surprise that InterruptedException is considered fatal by Scala's NonFatal. It's not clear to me or Daniel S why this is the case.

An example where you could reasonably get InterruptedExceptions cropping up on the runtime, is where a Resource creates a threadpool, runs some fibers on it, and cleans that threadpool up by interrupting+joining its threads. Depending on what those fibers are doing at the time the pool is shutdown, they may raise InterruptedExceptions.

Daniel suggested that since we already have so much exception-handling machinery, it is not a huge lift to have our own "NonFatal" that considers InterruptedException to indeed be non-fatal.

@djspiewak
Copy link
Member

Searching my memory banks... I think @viktorklang might be the only one with all the context on why InterruptedException was excluded from NonFatal in the first place. If I had to guess, it was a decision made to try to encourage user code to not handle it (since most of the time, catching it is a bad idea). In a sense, InterruptedException falls in a weird middle ground between truly fatal things like OOM and completely benign things like IOException, where it's not safe to treat it like other exceptions, but it's also not really something that burns down the JVM on its way out the door.

@kapunga
Copy link
Contributor

kapunga commented Jan 31, 2025

Was taking a look at this to maybe open a PR. In addition to InterruptedException, the normal Scala NonFatal accepts VirtualMachineError, ThreadDeath,LinkageError, and ControlThrowable as fatal, while the fs2 NonFatal only accepts VirtualMachineError. Is there any reason why the other three weren't included? As far as I can tell:

  • ThreadDeath - occurs when someone calls Thread.stop(), which has been deprecated since Java 1.2 and no one should be doing ever.
  • ControlThrowable - base Exception class for exceptions which are thrown for flow control, which at the very least breaks referential transparency and in my opinion no one should be doing ever.
  • LinkageError - occurs when there is a compiled incompatibility between a class and one that it depends on (signature change?) which seems highly unlikely and unrecoverable. I'm not even sure how this would happen happen anymore, maybe some library eviction on compilation?

Is there any reason why VirtualMachineError, ThreadDeath,LinkageError, and ControlThrowable shouldn't all be fatal? I don't see one.

@armanbilge
Copy link
Member Author

Thanks @kapunga! I'd start with the current implementation of Scala's NonFatal, minus the InterruptedException. In the future if we encounter other bugs and determine that another one of these exceptions does not need to be considered fatal, it should be easy enough to make the change :)

@kapunga
Copy link
Contributor

kapunga commented Jan 31, 2025

I opened a Draft PR here: #4263

Right now, I'd love feedback on the naming, placement, and documentation of UnsafeNonFatal. I'll be going through later to see if I can figure out what usages of scala.util.control.NonFatal should be replaced with UnsafeNonFatal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants