Error handling with coroutines
Ahmed-Adel-Ismail opened this issue · 2 comments
Ahmed-Adel-Ismail commented
The documentation does not tell how to handle failed responses when expecting a Deferred object ?
bradynpoulsen commented
This would be resolved when you join()
or await()
on the Deferred
in your coroutine.
For example, let's say that the following call raised a MissingParameterException
during conversion
interface UserService {
@GET("/user/{id}")
fun find(@Path("id") id: Int): Deferred<User>
}
fun foo() {
val retrofit = Retrofit.Builder().addCallAdapterFactory(...).build()
val service = retrofit.create(UserService::class.java)
val syncCurrentUserJob = launch(MySyncContext) {
val deferredUser = service.find(currentUserId)
val user = try {
deferredUser.await()
} catch (missingParam: MissingParameterException) {
// our conversion failed, wrap it in an exception specific to syncing
throw SyncFailedException("failed to sync current user: $currentUserId", cause = missingParam)
}
userRepo.update(user)
}
// our job caught the MissingParameterException and wrapped it in SyncFailedException
// calling `.join()` will raise any exception that occurred during the Job (in our case, the wrapping SyncFailedException
runBlocking { syncCurrentUserJob.join() }
}
Documentation for Deferred<out T>.await()
Awaits for completion of this value without blocking a thread and resumes when deferred computation is complete,
returning the resulting value or throwing the corresponding exception if the deferred had completed exceptionally.
Ahmed-Adel-Ismail commented
Thanks