@@ -18,9 +18,8 @@ internal expect fun handleCoroutineExceptionImpl(context: CoroutineContext, exce
1818 *
1919 * If there is a [Job] in the context and it's not a [caller], then [Job.cancel] is invoked.
2020 * If invocation returned `true`, method terminates: now [Job] is responsible for handling an exception.
21- * Otherwise, If there is [CoroutineExceptionHandler] in the context, it is used.
22- * Otherwise all instances of [CoroutineExceptionHandler] found via [ServiceLoader] and [Thread.uncaughtExceptionHandler] are invoked
23- *
21+ * Otherwise, If there is [CoroutineExceptionHandler] in the context, it is used. If it throws an exception during handling
22+ * or is absent, all instances of [CoroutineExceptionHandler] found via [ServiceLoader] and [Thread.uncaughtExceptionHandler] are invoked
2423 * todo: Deprecate/hide this function.
2524 */
2625@JvmOverloads // binary compatibility
@@ -39,21 +38,25 @@ private fun handleExceptionViaJob(context: CoroutineContext, exception: Throwabl
3938}
4039
4140internal fun handleExceptionViaHandler (context : CoroutineContext , exception : Throwable ) {
41+ // Invoke exception handler from the context if present
4242 try {
43- // Invoke exception handler from the context if present
4443 context[CoroutineExceptionHandler ]?.let {
4544 it.handleException(context, exception)
4645 return
4746 }
48- // If handler is not present in the context, fallback to the global handler
49- handleCoroutineExceptionImpl(context, exception)
50- } catch (handlerException: Throwable ) {
51- // simply rethrow if handler threw the original exception
52- if (handlerException == = exception) throw exception
53- // handler itself crashed for some other reason -- that is bad -- keep both
54- throw RuntimeException (" Exception while trying to handle coroutine exception" , exception).apply {
55- addSuppressedThrowable(handlerException)
56- }
47+ } catch (t: Throwable ) {
48+ handleCoroutineExceptionImpl(context, handlerException(exception, t))
49+ return
50+ }
51+
52+ // If handler is not present in the context or exception was thrown, fallback to the global handler
53+ handleCoroutineExceptionImpl(context, exception)
54+ }
55+
56+ internal fun handlerException (originalException : Throwable , thrownException : Throwable ): Throwable {
57+ if (originalException == = thrownException) return originalException
58+ return RuntimeException (" Exception while trying to handle coroutine exception" , thrownException).apply {
59+ addSuppressedThrowable(originalException)
5760 }
5861}
5962
0 commit comments