Kotlin协程场景下的异常正确处理方案相关问题咨询
Kotlin 协程异常处理实操方案
核心原则:区分异常类型
- 非预期异常:包括空指针、参数非法、序列化失败等代码逻辑错误,这类异常不需要捕获包裹,直接抛出即可,依赖协程的结构化并发机制自动取消整个作用域,避免后续无效代码执行。
- 预期内异常:包括网络IO异常、服务端返回的业务错误、用户输入非法等可预知的业务场景异常,这类异常才需要捕获后用自定义Result类包裹返回,向上层暴露可处理的错误状态。
Result模式与协程并发的适配方案
场景1:多个并发任务需「一失败即全部取消」
在coroutineScope中调用async时,对返回Result的方法调用getOrThrow(),如果Result为错误状态直接抛出异常,触发整个作用域的自动取消,符合99%的常规业务场景预期,示例代码:
coroutineScope { val r1 = async { api.fetchUserInfo().getOrThrow() } val r2 = async { api.fetchOrderList().getOrThrow() } val userInfo = r1.await() val orderList = r2.await() // 处理正常业务逻辑 }
场景2:多个并发任务需「独立处理结果互不影响」
使用supervisorScope替代普通coroutineScope,该作用域下单个子协程的失败不会传导到其他子协程或父协程,每个async块内自行处理异常并返回Result即可,示例代码:
supervisorScope { val r1 = async { api.fetchUserInfo() } val r2 = async { api.fetchOrderList() } // 分别处理两个请求的成功/失败状态 when(val userRes = r1.await()) { is Result.Success -> 处理用户信息逻辑 is Result.NetworkError -> 处理网络错误逻辑 else -> 其他错误处理 } when(val orderRes = r2.await()) { is Result.Success -> 处理订单列表逻辑 else -> 错误处理 } }
补全无受检异常的检查缺失
- 所有可能返回预期异常、需要上层处理的方法,添加Kotlin官方
@Throws注解标注可能抛出的异常类型,IDE会给出隐性提示,团队内部也可以约定返回Result的方法统一添加Result后缀,调用者可以直观识别需要处理错误状态。 - 异常捕获时严格限定捕获范围,禁止无差别捕获所有Throwable,仅捕获预期内的异常类型,非预期异常直接抛出走结构化取消逻辑,示例:
suspend fun fetchDataResult(): Result<Data> { return try { Result.Success(api.call()) } catch(ex: IOException) { Result.NetworkError } catch(ex: BusinessException) { Result.BizError(ex.code) } // 其他异常直接抛出不捕获 }
内容的提问来源于stack exchange,提问作者Ufkoku
相关产品推荐
相关产品推荐

