我有以下代码片段用于测试目的;
fun main() {
val myScope = CoroutineScope(Dispatchers.Default) + Job()
myScope.launch {
val job = async {
delay(1000)
throw RuntimeException("shiiiet")
}
try {
job.await()
} catch (ret: RuntimeException){
throw RuntimeException("yooo!")
}
}
try {
Thread.sleep(5000)
} catch(e: Exception){
}
println("wohoooo!")
}
我以为流量永远不会到达最后一个“呜呼!”行,但我错了。我看到它印在屏幕上。我想到的原因是
launch
会将异常传播到父作用域,并且由于父作用域不处理它,它会在到达打印语句时使 JVM 崩溃。这是因为父作用域在其子作用域失败后被取消,收到 CancellationException 并被忽略吗?
最佳答案
您尝试了多个 throw
和 catch
在你的例子中的方法。async
按预期工作 - 当您 await
为此,您可以捕获异常。但是如果你launch
一个协程,默认Thread.uncaughtExceptionHandler
只是将结果打印到控制台。
即使你这样做
myScope.launch {
....
}.invokeOnCompletion { e -> println("Exception: $e") }
您仍然会在控制台上额外获得结果。
解释了传播规则和处理异常的不同类型的调用 here .
关于如何在“main”协程中捕获异常的示例:
fun main() = runBlocking {
try {
GlobalScope.launch {
delay(10)
throw Exception("You don't catch me in main.")
}
launch {
delay(10)
throw Exception("You catch me in main.")
}
delay(100)
println("Never reached.")
} catch(e: Exception) {
println("Caught in main: ${e.cause}")
}
println("The end")
}
关于kotlin - 范围是否在幕后默默地处理异常/失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60658586/