Abhimanyu
09/16/2025, 3:48 AMAbhimanyu
09/16/2025, 3:48 AMfun initViewModel(): Job {
return coroutineScope.launch {
coroutineScope.launch { // Observes data 1 continuously
observeData1().collectLatest {
refreshUiState()
}
}
coroutineScope.launch { // Observes data 2 continuously
observeData2().collectLatest {
refreshUiState()
}
}
fetchData1() // Can throw an exception like "IllegalArgumentException"
}
}
Currently, when fetchData1() throws an exception, initViewModel() throws JobCancellationException instead of the exception thrown by fetchData1() .
How to make initViewModel() throw the actual exception thrown by fetchData1() ?Sergey Dmitriev
09/16/2025, 6:46 AMcoroutineScope your custom scope that you created?Sergey Dmitriev
09/16/2025, 6:49 AMobserveData1() and observeData2() you can omit coroutinseScope and just use
coroutineScope.launch {
launch {
// 1
}
launch {
// 2
}
}
I believeDeeksha Agrawal
09/18/2025, 6:31 AMfetchData1() in async and await
something like this
fun initViewModel(): Job {
return coroutineScope.launch {
val job1 = launch { observeData1().collectLatest { refreshUiState() } }
val job2 = launch { observeData2().collectLatest { refreshUiState() } }
val deferred = async { fetchData1() }
deferred.await() // exception propagates here
}
}Abhimanyu
09/18/2025, 5:14 PMcoroutineScope is injected and used like this.
CoroutineScope(
dispatcherProvider.mainImmediate + SupervisorJob(),
)
internal class EditAccountScreenViewModel(
private val coroutineScope: CoroutineScope,
//
) : ViewModel(
viewModelScope = coroutineScope,
)
Can ignore the observing data part it is just a sample example.
The main question I have is how to rethrow exception from fetchData.Abhimanyu
09/18/2025, 5:17 PMval deferred = async { fetchData1() }
deferred.await() // exception propagates here
is same as
val deferred = async { fetchData1() }.await() // exception propagates here
So, the async is called followed immediately by await() .
fetchData1() is a suspending method and it seems equivalent to my original code.
I tried this as well to see if it makes any difference in error handling, and I observed that it doesn’t.Deeksha Agrawal
09/19/2025, 6:16 AMrunCatching {
fetchData1()
}.onFailure { e ->
}