EARTH H
EARTH H

Reputation: 67

Why is exception handled by the handler of a child coroutine not parent?

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?

Upvotes: 0

Views: 119

Answers (1)

Nongthonbam Tonthoi
Nongthonbam Tonthoi

Reputation: 12963

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")
    }
}

Upvotes: 0

Related Questions