本篇解析 example-exceptions-06.kt。探讨协程在取消过程中的异常“透明”特性。
1. 核心概念:透明且未包装
在 Kotlin 协程中,取消异常(CancellationException)是透明的。
特点:
- 不被包装:当一个协程被取消时,它会抛出
CancellationException。这个异常不会被包装 in 其他异常中,而是以原始形式抛出。 - 重新抛出:如果你捕获了
CancellationException,通常建议将其重新抛出。这有助于协程库正确地传播取消信号,并完成结构化并发的清理工作。
2. 代码解析
1 | val job = GlobalScope.launch(handler) { |
- 执行逻辑:
- 最深层的子协程抛出
IOException。 - 这导致整个
inner协程树被取消。 - 父协程在
inner.join()处捕获到CancellationException。 - 即使父协程重新抛出了
CancellationException,最外层的handler最终捕获到的依然是那个引发一切的原始异常:IOException。
- 最深层的子协程抛出
3. 开发者感悟
“取消透明性”保证了异常源头不会被掩盖。在复杂的嵌套协程中,你不需要担心中间层级的 try-catch 会让真实的报错信息丢失。只要遵循“捕获后重新抛出”的原则,协程库就能确保原始的错误根源最终能到达你的全局异常处理器中。