【发布时间】:2019-05-02 02:41:24
【问题描述】:
我在使用协程进行错误处理时遇到问题,我已通过以下步骤将其范围缩小到此单元测试:
- 我使用任何调度程序创建一个协程范围。
- 我在异步块(甚至嵌套的异步块)中此范围内的任何位置抛出异常。
- 我对返回的延迟值调用 await 并处理异常。
-
这一切都很好。但是,当我尝试使用相同的协程范围来启动新的协程时,这总是异常完成并出现相同的异常。
这是测试:
fun `when you throw an exception in a coroutine scope, is the coroutine scope dead?`() { val parentJob = Job() val coroutineScope = CoroutineScope(parentJob + Dispatchers.Default) val deferredResult = coroutineScope.async { throw IllegalStateException() } runBlocking { try { deferredResult.await() } catch (e: IllegalStateException) { println("We caught the exception. Good.") } try { coroutineScope.async { println("we can still use the scope") }.await() } catch (e: IllegalStateException) { println("Why is this same exception still being thrown?") } } }
这是测试的输出:
We caught the exception. Good.
Why is this same exception still being thrown?
-
为什么会这样?
- 我的理解是您可以正常处理异常并使用协程从异常中恢复。
-
我应该如何处理异常?
- 我需要创建一个新的 coroutineScope 吗?
- 如果我想继续使用同一个 coroutineScope,我可以从不抛出异常吗?
- 我应该返回
Either<Result, Exception>吗? - 我尝试过使用 CoroutineExceptionHandler,但仍然得到相同的结果。
注意我使用的是 Kotlin 1.3
【问题讨论】:
-
通过查看 CoroutineScope javadoc:“取消或失败或此范围内的任何子协程都会取消所有其他子协程”。所以也许我需要为每个调用创建一个新的范围。
-
将
SupervisorJob用作parentJob。
标签: kotlin error-handling kotlin-coroutines