Hey I have a question: ```fun main() = runBlocking...
# coroutines
k
Hey I have a question:
Copy code
fun main() = runBlocking {
    try {
        cScope()
    } catch (error: Throwable) {
        println(error)
    }
}

suspend fun cScope() = coroutineScope {
    val def = async { failure() }
    try {
        def.await()
    } catch (error: Throwable) {
        println(error)
    }
}
Why is it only possible to
catch
the error when wrapping
cScope()
and not
def.await()
?
a
When async throws an exception, it automatically cancels the scope, so you can't just catch the exception when retrieving. To be fair, I'm still not 100% sure how to properly catch errors, but adding an exception handler seems to be the best alternative
k
I see that the only way to catch them is via
supervisionScope
. But how can I handle this on Android using a
ViewModel
and implementing
CoroutineScope
. How can I there handle any exceptions without cancelling my scope forever?
a
When you define a new inner scope like in your code, the error should only propagate to that scope. You can also set an error handler (forgot the method name) within it. I do have the same problem with my code though, which I've asked in previous threads. I haven't had time to test but exception handler seems like the way to go. À supervisor scope adds a supervisor job to the scope, meaning that exceptions in children should not affect other children. I already have a supervisor in my top level scope though so I'm not sure if that alone is a suitable solution
k
If you use
supervisorScope
unhandled exceptions will affect other children. So if I change
coroutineScope
to it in my example and I remove the
try/catch
in the
fun cScope
then other children would be cancelled.
But what will happen on Android if my component implements
CoroutineScope
and I use async and the async throws? How can I catch the error? Will my scope then be cancelled forever?
a
What's your test code example? The point of the supervisor is to disallow exceptions from propagating upwards. I might have to read more into the docs
k
Copy code
suspend fun cScope() = supervisorScope {
    val def = async { failure() }
    def.await()
    suspendingWork()
}
That will cancel the scope as I am not wrapping the await in
try/catch
If I wrapped it would not fail the scope because I am using
supervisorScope
. If I would use
coroutineScope
then it would not matter if I had used
try/catch
or not
a
This makes sense because it throws an exception. What I'm saying is that you probably won't need to wrap failure within async, whereas if you didn't have a supervisor scope the internal failure would have cancelled your scope even if you caught await
👍 1
g
This is how coroutineScope works, thows an exception that cause of child coroutines to fail. To handle error just wrap call of coroutineScope to try/catch or use supervisorScope
But what will happen on Android if my component implements
CoroutineScope
and I use async and the async throws? How can I catch the error? Will my scope then be cancelled forever?
Yes, it will be cancelled this is why for UI use cases SuervisorJob is better choice than Job