David Glasser
08/28/2019, 6:00 AMimport kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.system.exitProcess
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, t ->
println("handling exception: $t")
exitProcess(1)
}
coroutineScope {
launch(handler) {
println("running")
throw Exception("OMG")
}
}
Unit
}
I would expect this to print "handling exception" and exit the process. Instead it shows that an exception was unhandled in main
(I'll paste in the thread)running
Exception in thread "main" java.lang.Exception: OMG
at mdg.engine.selfmonitoring.TmpKt$main$1$1$1.invokeSuspend(tmp.kt:17)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:270)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at mdg.engine.selfmonitoring.TmpKt.main(tmp.kt:9)
at mdg.engine.selfmonitoring.TmpKt.main(tmp.kt)
This also a reason why, in these examples, CoroutineExceptionHandler is always installed to a coroutine that is created in GlobalScope. It does not make sense to install an exception handler to a coroutine that is launched in the scope of the main runBlocking, since the main coroutine is going to be always cancelled when its child completes with exception despite the installed handler.at https://kotlinlang.org/docs/reference/coroutines/exception-handling.html
gildor
08/28/2019, 6:34 AMDavid Glasser
08/28/2019, 7:53 AM