I',m trying to test coroutineExceptionHandler.
Here is my code.
fun main(): Unit = runBlocking {
code1_9()
}
fun createExceptionHandler(name: String) = CoroutineExceptionHandler { context, throwable ->
println("[${Thread.currentThread().name} - $name] Caught $throwable")
}
suspend fun code1_9() = coroutineScope {
val supervisorScope = CoroutineScope(SupervisorJob() + createExceptionHandler("supervisor"))
supervisorScope.apply {
launch(CoroutineName("launch1") + createExceptionHandler("launch1")) {
throw Exception("[${Thread.currentThread().name}] Error !")
}
launch(CoroutineName("launch2")) {
println("[${Thread.currentThread().name}] launch2")
}
}
delay(1000L)
}
Result:
[DefaultDispatcher-worker-2 @launch2#3] launch2
[DefaultDispatcher-worker-1 @launch1#2 - launch1] Caught java.lang.Exception: [DefaultDispatcher-worker-1 @launch1#2] Error !
I expect supervisorScope's handler will be chosen, but launch handler caught the exception.
Why the exception caught in child coroutine? Isn't the supervisorScope root coroutine?
What you are doing is similar to:
supervisorScope.launch(CoroutineName("launch1") + createExceptionHandler("launch1")) {
throw Exception("[${Thread.currentThread().name}] Error !")
}
supervisorScope.launch(CoroutineName("launch2")) {
println("[${Thread.currentThread().name}] launch2")
}
To make the parent handle the exception change apply
to launch
supervisorScope.launch {
launch(CoroutineName("launch1") + createExceptionHandler("launch1")) {
throw Exception("[${Thread.currentThread().name}] Error !")
}
launch(CoroutineName("launch2")) {
println("[${Thread.currentThread().name}] launch2")
}
}