Exceptions in launch and async

Propagation Rules

BuilderException isCatch it with
launchpropagated to the parent at oncetry/catch inside the coroutine, or CoroutineExceptionHandler on the root
asyncstored in the Deferred, thrown again by await() (and also propagated to the parent)try/catch around await() inside supervisorScope, or around coroutineScope

Note: A try/catch around launch { } does nothing: launch returns immediately, the exception happens later inside the new coroutine.

Example

Example

import kotlinx.coroutines.*

fun main(): Unit = runBlocking {
    // 1. try/catch inside the coroutine
    launch {
        try {
            error("network down")
        } catch (e: IllegalStateException) {
            println("1. caught inside launch: ${e.message}")
        }
    }.join()

    // 2. async: the exception is thrown by await()
    supervisorScope {
        val price = async<Int> { throw ArithmeticException("bad price") }
        try {
            price.await()
        } catch (e: ArithmeticException) {
            println("2. caught at await: ${e.message}")
        }
    }

    // 3. coroutineScope rethrows a child failure to the caller
    try {
        coroutineScope {
            launch { delay(50); throw IllegalArgumentException("invalid coupon") }
        }
    } catch (e: IllegalArgumentException) {
        println("3. caught around coroutineScope: ${e.message}")
    }
}

Output

1. caught inside launch: network down
2. caught at await: bad price
3. caught around coroutineScope: invalid coupon