【发布时间】:2021-04-15 07:26:52
【问题描述】:
我有一个async 协程,它可能会引发异常。如何将异常传播到我的CoroutineExceptionHandler?在 try/catch 附近使用 await 我能够捕获异常,但无论上下文如何,我似乎都无法将处理传播到处理程序:
val handler = CoroutineExceptionHandler { _, e -> e.printStackTrace() }
val context = Executors.newSingleThreadExecutor().asCoroutineDispatcher() + handler
val scope = CoroutineScope(context)
val async = scope.async {
throw Exception("Test exception")
}
runBlocking {
try {
async.await()
} catch (e: Exception) {
log.error("Exception thrown", e)
}
delay(1_000)
}
我已经尝试从 catch 中重新抛出异常,或者使用以下一些构造来包装它:
catch (e: Exception) {
throw e
// withContext(context) { throw e }
// scope.launch { throw e }
// supervisorScope { throw e }
}
遗憾的是,它们都没有将其传播给处理程序。我可以以某种方式将CoroutineExceptionHandler 与async 协同程序一起使用吗?
【问题讨论】:
-
你确定你真的需要
async吗?您的示例肯定不会激发它,您忽略了await)的结果。您的async是否执行您等待其结果的计算?或者它只是执行一项任务?通常,如果您在后台执行计算,那是因为您正在并行执行多个计算,然后使用它们的结果,所有这些都在一个工作单元的范围内。在这种情况下,您只需在该工作单元周围使用简单的 try-catch。 -
是的,我的用例是流中的并行异步计算,然后我等待结果以维护上游顺序。我只是想让这个例子变得简单,显然以更高的混淆机会为代价:)
-
难道你不能将所有并行工作包装在
coroutineScope中,在单个外部try-catch 中处理其中的任何错误吗?我认为这就是 Kotlin 希望你这样做的方式,而CoroutineExceptionHandler只是作为最后的机制来让你知道,由于你的程序中的一个错误,一个未处理的异常爆发了。正是在整个 Kotlin 协程设计中严格遵守这一意图,您在使用它时遇到问题。
标签: kotlin asynchronous kotlin-coroutines