CoroutineExceptionHandler 是 Kotlin 协程中用于处理未捕获异常的全局兜底机制,但它并非万能的。理解其确切的使用场景和固有的局限性,对于在字节跳动这样复杂的产品中构建稳定的异步架构至关重要。我将从它的设计初衷、正确用法以及必须警惕的陷阱这几个方面来详细阐述。”
第一部分:核心使用场景
CoroutineExceptionHandler 的本质是一个 “最后防线” ,用于捕获那些在协程体中未被局部处理的、未被捕获的异常。
1. 全局异常捕获与上报
这是最经典和主要的用途。在 Android 应用中,我们希望避免因协程中的未处理异常而导致应用崩溃,同时需要将错误信息上报到监控平台。
kotlin
// 在 Application 或顶级 Scope 中定义
val GlobalExceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
// 1. 记录详细的上下文信息
val coroutineName = coroutineContext[CoroutineName]?.name ?: "unknown"
// 2. 增强异常信息(添加上下文)
val enhancedException = EnhancedException("Coroutine '$coroutineName' failed", throwable)
// 3. 上报到监控平台(如 Firebase Crashlytics, Sentry, 自研APM)
FirebaseCrashlytics.getInstance().apply {
setCustomKey("coroutine_name", coroutineName)
setCustomKey("occurrence_time", System.currentTimeMillis())
recordException(enhancedException)
}
// 4. 根据业务逻辑,可能需要进行恢复或降级处理
if (throwable is NetworkTimeoutException) {
// 可以在这里发送一个事件,通知UI显示网络超时提示
EventBus.getDefault().post(NetworkErrorEvent)
}
}
// 在应用的全局 Scope 中使用
val applicationScope = CoroutineScope(SupervisorJob() + GlobalExceptionHandler)
// 在任何地方使用这个 scope 启动协程,未捕获的异常都会被全局处理器捕获
fun fetchUserData() {
CoroutineExceptionHandler使用与局限

最低0.47元/天 解锁文章
2811

被折叠的 条评论
为什么被折叠?



