Hi! I ran into error handling behaviour I don’t un...
# coroutines
v
Hi! I ran into error handling behaviour I don’t understand, can someone explain it to me? I prepared a repo with simplified example. I have an async call in on a ViewModel scope, if I use try/catch, catch code is hit, but app crashes
Copy code
fun loadData() {
        viewModelScope.launch {
            try {
                greeting.value = async { getGreetingUseCase() }.await()
            }
            catch (e: CancellationException){
                throw e
            }
            catch (e: Exception) {
                greeting.value = "Error occurred!"
            }
        }
    }
But with
CoroutineExceptionHandler
it works without crashes.
Copy code
fun loadDataWithCoroutineExceptionHandler() {
        val exceptionHandler = CoroutineExceptionHandler { _, exception ->
            greeting.value = "Error occurred!"
        }
        viewModelScope.launch(exceptionHandler) {
            greeting.value = async { getGreetingUseCase() }.await()
        }
    }
d
async
reports its error in two places: • The exception is propagated to the parent coroutine (in this case, to
viewModelScope.launch
); • The exception is also stored in the
Deferred
as the result of the computation. When you catch the exception thrown by
await
(the second place where the exception is stored), this doesn't stop the
launch
from learning that one of its children failed, and so it fails, too.
🥴 1
👀 1
v
I didn’t expect it to work that way, thanks for explanation 🙌