@Keep | |
internal class LoggingHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler), | |
CoroutineExceptionHandler { | |
override fun handleException(context: CoroutineContext, exception: Throwable) { | |
Crashlytics.logException(exception) | |
// Since we don't want to crash and Coroutines will call the current thread's handler, we | |
// install a noop handler and then reinstall the existing one once coroutines calls the new | |
// handler. | |
Thread.currentThread().apply { | |
// _Do_ crash the main thread to ensure we're not left in a bad state | |
if (isMain) return@apply | |
val removed = uncaughtExceptionHandler | |
uncaughtExceptionHandler = if (removed == null) { | |
ResettingHandler | |
} else { | |
Thread.UncaughtExceptionHandler { t, _ -> | |
t.uncaughtExceptionHandler = removed | |
} | |
} | |
} | |
} | |
private object ResettingHandler : Thread.UncaughtExceptionHandler { | |
override fun uncaughtException(t: Thread, e: Throwable) { | |
t.uncaughtExceptionHandler = null | |
} | |
} | |
} | |
val Thread.isMain get() = this === Looper.getMainLooper().thread |
# Put in file src/main/resources/META-INF/services/kotlinx.coroutines.CoroutineExceptionHandler | |
com.supercilex.robotscouter.core.LoggingHandler |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment