You should use retryWhen
operator like you said.
http://reactivex.io/documentation/operators/retry.html
See under retryWhen
section of RxKotlin
.
RetryWhen
operator "resubscribes" when inner observable emits an item (Observable's onNext or Single's onSuccess is called) or just does not retry and pass the throwable downstream when onError
I called.
Above is my wording; the exact wording from the doc is as follows:
The retryWhen operator is similar to retry but decides whether or not
to resubscribe to and mirror the source Observable by passing the
Throwable from the onError notification to a function that generates a
second Observable, and observes its result to determine what to do. If
that result is an emitted item, retryWhen resubscribes to and mirrors
the source and the process repeats; if that result is an onError
notification, retryWhen passes this notification on to its observers
and terminates.
Suppose you have the following retrofit interface.
interface Api {
@GET("/api")
fun request(): Single<String>
}
In the retry block, you get a flowable of throwable (which will be mostly HttpException
thrown from your retrofit interface), You should use flatMap
operator on this flowable because you have to pass the throwable downstream when network is still not available.
ApiClient.instance.request()
.retryWhen { flowable: Flowable<Throwable> ->
flowable.flatMap { throwable ->
// check network status here
if (available) return@flatMap Flowable.just<Boolean>(true)
return@flatMap Flowable.error<Boolean>(throwable)
}
}
.subscribe({ response -> /* deal with success */}, { error -> /* deal with error */})
Watch out here that you have to match the type of retrying case and throwing case (Flowable<Boolean>
in this case). It usually doesn't matter which type use choose as long as you emit an item when you want to retry and an error when you don't want to.