Reputation: 11035
fun main() = runBlocking {
coroutineScope {
val child = async {
Log.e("+++", "+++ in async{}, throw exception , ${Thread.currentThread().name}")
throw Exception("test exception with await() in async")
}
try {
child.await()
} catch(ex: Throwable) {
Log.e("+++", "+++ child.await() caught exception $ex, ${Thread.currentThread().name}")
}
}
}
The log "+++ child.await() caught exception java.lang.Exception: test exception with await() in aync, main"
. shows the exception is caught, but it still crashes the app.
Why the expiation caught is still crashing the app with coroutines?
Upvotes: 0
Views: 683
Reputation: 1337
Exception thrown by the child coroutine bubbles up to its immediate parent. You must try catching exceptions in parent coroutines. This way application won't crash.
Upvotes: 0
Reputation: 11035
find this is helpful as well, and here:
whenever a coroutine created by async() throws an exception,
the same exception is thrown both by its Deferred.await()
and inside the body of the parent coroutine as well!
This means that, no matter if we catch the exception by surrounding await() with try/catch,
our app is still going to crash because the exception is not thrown just
from the await() suspension point
Upvotes: 1
Reputation: 25603
As per the documentation of coroutineScope
:
This function is designed for parallel decomposition of work. When any child coroutine in this scope fails, this scope fails and all the rest of the children are cancelled (for a different behavior see supervisorScope). This function returns as soon as the given block and all its children coroutines are completed.
Remove the coroutineScope
and it should function as you are expecting it should.
Upvotes: 1