(Kotlin协程十六)try/catch 可以捕获子协程的异常吗?为什么?
这是一个关于协程异常处理边界的关键问题。简单的回答是:常规的
try/catch
无法直接捕获由launch
启动的子协程内部抛出的异常。 但这背后的‘为什么’才是重点,它涉及到协程的并发执行模型、异常传播机制以及结构化并发的设计哲学。”
第一部分:核心答案与现象演示
为什么 try/catch 无效?
因为 launch
启动的协程是并发执行的。父协程不会等待子协程完成,它会继续向下执行。当子协程在后台抛出异常时,父协程的 try/catch
块早已执行完毕,异常抛出的时空与 try/catch
的监控范围完全错开。
代码示例:
kotlin
fun main() = runBlocking {try {// 父协程启动一个子协程后立即继续,不等待launch {// 这个协程在后台并发执行delay(100) // 模拟一些工作throw RuntimeException("Boom from child!") // 异常在后台抛出}// 父协程会立即执行到这里,try 块已经结束!println("Parent coroutine continues...")delay(200) // 等待一段时间,确保能看到子协程的异常结果} catch (e: Exception) {// 这个 catch 块永远抓不到来自 launch 子协程的异常