我测试了 coroutineExceptionHandler。
这是我的代码。
fun createExceptionHandler(name: String) = CoroutineExceptionHandler { context, throwable ->
println("[${Thread.currentThread().name} - $name] Caught $throwable\n${context[CoroutineExceptionHandler]}")
}
@Test
fun coroutineScope_exceptionHandle() = runBlocking<Unit> {
val coroutineScope = CoroutineScope(Job() + createExceptionHandler("supervisor"))
coroutineScope.launch(createExceptionHandler("launch1")) {
launch(CoroutineName("launch2") + createExceptionHandler("launch2")) {
throw Exception("[${Thread.currentThread().name}] Error !")
}
launch(CoroutineName("launch3")) {
println("[${Thread.currentThread().name}] launch3")
}
}
delay(1000L)
}
结果:
[DefaultDispatcher-worker-3 @launch3#6] launch3
[DefaultDispatcher-worker-2 @launch2#5 - launch1] Caught java.lang.Exception: [DefaultDispatcher-worker-2 @launch2#5] Error !
...
我希望异常由 coroutineScope 的名为主管的处理程序处理。
您能解释一下为什么launch1处理程序会处理异常吗?
launch
函数的 CoroutineScope 参数的工作方式是,它将父作用域的所有部分替换为您传递的作用域参数中定义的部分。
当您调用
launch
时,您向其传递了一个由新异常处理程序 ("launch1"
) 组成的作用域。此异常处理程序将替换父协程作用域中启动的协程运行范围中的异常处理程序。