Skip to content

Conversation

dkhalanskyjb
Copy link
Collaborator

Fixes #4516

Background

Whenever an uncaught exception happens in a coroutine, it gets reported to the CoroutineExceptionHandler. See https://kotlinlang.org/docs/exception-handling.html#coroutineexceptionhandler. However, if it's not installed, a platform-specific handler is used.
On the JVM, this means invoking the thread's
UncaughtExceptionHandler, which logs the exception to the console by default, but can be configured to do other things (for example, on Android, it will crash the application).

Problem

User-specified UncaughtExceptionHandler instances are allowed to throw exceptions.
Java's documentation says so
(https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.UncaughtExceptionHandler.html):

Any exception thrown by this method will be ignored by the Java Virtual Machine.

This means a user is allowed to write a throwing
UncaughtExceptionHandler, and the caller has to deal with it.

In our implementation, however, we are simply invoking the exception handler as a plain function, and if that function throws an exception, we allow this exception to propagate to the coroutine machinery, causing it to fail.

Solution

To comply with the contract defined for UncaughtExceptionHandler, we also ignore the exceptions thrown from there.

Fixes #4516

Background
----------

Whenever an *uncaught* exception happens in a coroutine,
it gets reported to the `CoroutineExceptionHandler`.
See <https://kotlinlang.org/docs/exception-handling.html#coroutineexceptionhandler>.
However, if it's not installed, a platform-specific handler
is used.
On the JVM, this means invoking the thread's
`UncaughtExceptionHandler`, which logs the exception to the console
by default, but can be configured to do other things
(for example, on Android, it will crash the application).

Problem
-------

User-specified `UncaughtExceptionHandler` instances are allowed to
throw exceptions.
Java's documentation says so
(https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.UncaughtExceptionHandler.html):
> Any exception thrown by this method will be ignored by the Java Virtual Machine.

This means a user is allowed to write a throwing
`UncaughtExceptionHandler`, and the caller has to deal with it.

In our implementation, however, we are simply invoking the
exception handler as a plain function, and if that function
throws an exception, we allow this exception to propagate
to the coroutine machinery, causing it to fail.

Solution
--------

To comply with the contract defined for `UncaughtExceptionHandler`,
we also ignore the exceptions thrown from there.
* > Any exception thrown by this method will be ignored by the Java Virtual Machine.
*
* This means the authors of the thread exception handlers have the right to throw exceptions indiscriminately.
* We have no further channels for propagating the fatal exception, so we give up. */
Copy link
Member

Choose a reason for hiding this comment

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

you can add something like val _ = "Welcome, weary traveler. To my breakpoint place" which is both self-explanatory and funny (okay, maybe only self-explanatory)

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 this pull request may close these issues.

2 participants