androidkotlinrx-javaretrofit2retrywhen

[RxJava]How to handle network error by `retryWhen()` on Android RxJava × retrofit2


I've trying https request on retrofit with RxJava

When network is not available, I want to handle like this. 1, check network status. 2, if network is available, retry request 3, if network is not available, no retry -> after that, listen network status and when it will be back, then retry request

I think we should use retryWhen() operator but I don't know hot to do this

need help to have good solution


Solution

  • 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.