Estou tentando entender por que a exceção é passada para cima na hierarquia no caso de async
não estar cercada por coroutineScope
? Por que não existe essa necessidade coroutineScope
ao lidar com exceções launch
?
fun main() {
runBlocking {
this.launch {// case 1
try {
throw java.lang.IndexOutOfBoundsException()
} catch (e: Exception) {
println("Caught IndexOutOfBoundsException")
}
}
try {
coroutineScope {
val deferred = async {// case 2
throw ArithmeticException()
}
deferred.await()
}
} catch (e: ArithmeticException) {
println("Caught ArithmeticException")
}
try {
val deferred = async {//case 3
throw ArithmeticException()
}
deferred.await()
} catch (e: Exception) {
println("Caught ArithmeticException but passed to root as well")
}
}
}
Minha saída atual é a seguinte:
Caught IndexOutOfBoundsException
Caught ArithmeticException
Caught ArithmeticException but passed to root as well
Exception in thread "main" java.lang.ArithmeticException
at TryItYourself3Kt$main$1$deferred$1.invokeSuspend(TryItYourself3.kt:26)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:95)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:69)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:48)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at TryItYourself3Kt.main(TryItYourself3.kt:5)
at TryItYourself3Kt.main(TryItYourself3.kt)
Process finished with exit code 1
Não tenho certeza se acertei sua pergunta:
Caso 1: capturamos a exceção antes que ela chegue ao maquinário das corrotinas, então as corrotinas nem sabem que houve uma exceção.
Caso 2:
async
é filho decoroutineScope
. Ambos falham, mas ambos estão entretry...catch
, então capturamos a exceção que vem decoroutineScope
.Caso 3:
async
é filho derunBlocking
, então ambos falham. Capturamos a falha dedeferred.await()
, masrunBlocking
ela ainda falha.