@@ -18,9 +18,8 @@ internal expect fun handleCoroutineExceptionImpl(context: CoroutineContext, exce
18
18
*
19
19
* If there is a [Job] in the context and it's not a [caller], then [Job.cancel] is invoked.
20
20
* 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
24
23
* todo: Deprecate/hide this function.
25
24
*/
26
25
@JvmOverloads // binary compatibility
@@ -39,21 +38,25 @@ private fun handleExceptionViaJob(context: CoroutineContext, exception: Throwabl
39
38
}
40
39
41
40
internal fun handleExceptionViaHandler (context : CoroutineContext , exception : Throwable ) {
41
+ // Invoke exception handler from the context if present
42
42
try {
43
- // Invoke exception handler from the context if present
44
43
context[CoroutineExceptionHandler ]?.let {
45
44
it.handleException(context, exception)
46
45
return
47
46
}
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)
57
60
}
58
61
}
59
62
0 commit comments