Exception not being caught in Coroutines

Trying with CoroutineExceptionHandler can be workaround for handling exceptions inside coroutines.

CoroutineExceptionHandler context element is used as generic catch block of coroutine where custom logging or exception handling may take place. It is similar to using Thread.uncaughtExceptionHandler.

How to use it?

val handler = CoroutineExceptionHandler { _, exception -> 
    println("Caught $exception") 
}
val job = GlobalScope.launch(handler) {
    throw AssertionError()
}
val deferred = GlobalScope.async(handler) {
    throw ArithmeticException() // Nothing will be printed, relying on user to call 
    deferred.await()
}
joinAll(job, deferred)

In your ViewModel, make sure that your uiScope is using SupervisorJob rather than Job. SupervisorJob's can handle its children's failure individually. Job would get cancelled unlike SupervisorJob

If you're using 2.1.0 for AAC Lifecycle and ViewModel, use the viewModelScope extension instead.


Another way to resolve this would be to covert your custom error object to implement CancellationException

For eg:

Your CustomException can be implemented as :

sealed class CustomError : CancellationException() {
        data class CustomException(override val message: String = "Checker Failed due to: ...") : CustomError
}

This exception would get caught in the try/catch block of the view model