-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathCoroutineExceptionHandlerImpl.kt
36 lines (31 loc) · 1.5 KB
/
CoroutineExceptionHandlerImpl.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines
import java.util.*
import kotlin.coroutines.*
/**
* A list of globally installed [CoroutineExceptionHandler] instances.
*
* Note that Android may have dummy [Thread.contextClassLoader] which is used by one-argument [ServiceLoader.load] function,
* see (https://stackoverflow.com/questions/13407006/android-class-loader-may-fail-for-processes-that-host-multiple-applications).
* So here we explicitly use two-argument `load` with a class-loader of [CoroutineExceptionHandler] class.
*/
private val handlers: List<CoroutineExceptionHandler> = CoroutineExceptionHandler::class.java.let { serviceClass ->
ServiceLoader.load(serviceClass, serviceClass.classLoader).toList()
}
internal actual fun handleCoroutineExceptionImpl(context: CoroutineContext, exception: Throwable) {
// use additional extension handlers
for (handler in handlers) {
try {
handler.handleException(context, exception)
} catch (t: Throwable) {
// Use thread's handler if custom handler failed to handle exception
val currentThread = Thread.currentThread()
currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, handlerException(exception, t))
}
}
// use thread's handler
val currentThread = Thread.currentThread()
currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, exception)
}