Reputation: 181
I'm trying to use Kotlin co-routines to trigger a network request and handle Exceptions. I've looked at a lot of tutorials on co-routines but I'm really struggling to relate what i know to the problem i have.
Trying to get an exception to be caught in the View, but no Exception is thrown from the ViewModel so the application crashes.
My Android app has three layers that relate to this issue. I have the View, ViewModel and a Service layer. In the service layer, request.execute() can throw a UserAuthException.
MyView (View)
private val mViewModel: MyViewModel by viewModels()
private fun getFileId() {
try {
mViewModel.requestFileId()
} catch (e: UserAuthException) {
Timber.i(e)
}
}
MyViewModel (ViewModel)
private val apiService = MyApiService()
fun requestFileId() {
viewModelScope.launch {
ApiService.requestFileId()
}
}
MyApiService (Service Layer)
suspend fun requestFileId(): FileId = withContext(Dispatchers.IO) {
request.execute()
}
I have played around with CoroutineExceptionHandlers, supervisorJobs with no luck, but without the fundamental knowledge of how these things work I'm not really making any progress.
Any help would be appreciated, thanks.
Upvotes: 1
Views: 147
Reputation: 200138
fun requestFileId() {
viewModelScope.launch {
ApiService.requestFileId()
}
}
This is not a suspendable function. It launches a concurrent coroutine and returns right away. Clearly, calling requestFileId()
will never throw an exception.
Launching a coroutine is just like starting another thread, it introduces concurrency to your code. If your current code hopes to stay non-concurrent while observing the results of suspendable functions, you may be looking at significant architectural changes to the application to make it behave correctly under concurrency.
Upvotes: 1
Reputation: 895
In your model, change it to something like this:
fun requestFileId() {
viewModelScope.launch {
try {
ApiService.requestFileId()
} catch (e: Exception) {
// inform your view
}
}
}
Upvotes: 0