RxJava for Android: Expose Exception and Retry (delayed)

I have the following Observable that will execute a REST-Call with completion every 30 seconds:

Subscription subscription = Observable.interval(0, REFRESH_INTERVAL, TimeUnit.SECONDS) .concatMap(new Func1<Long, Observable<Response>>() { @Override public Observable<Response> call(Long time) { return webservice.callRetrofitServiceWithRx(parameter); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new UpdateSuccessAction(), new UpdateErrorAction()); 

It may happen that (especially REST-Call) will throw an exception (for example, there is no Internet connection).

What I would like to achieve:

The monitored one should throw / throw an exception so that I can display an error message in the user interface, but it must continue to emit elements (try again after 30 seconds).

Current study

  • If I do not define any special behavior, the Observable throws an exception and stops working (= NO repeat in 30 seconds).

  • If I try the retry operator, the exception will be swallowed and will not be opened, so I cannot display the error in ui.

  • If I try the onErrorReturn statement, I can handle the exception, but as far as I know, retrying is not possible.

Bypass

My current workaround is to reconnect to this Observable, but I would like to know if anyone has a more elegant solution.

+5
source share
2 answers

I assume that doOnError will suit your needs (for registering an error), combined with repetition, for example:

 Subscription subscription = Observable.interval(0, REFRESH_INTERVAL, TimeUnit.SECONDS) .concatMap(new Func1<Long, Observable<Response>>() { @Override public Observable<Response> call(Long time) { return webservice.callRetrofitServiceWithRx(parameter); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError(new UpdateErrorAction()) .retry() .subscribe(new UpdateSuccessAction()); 
+4
source

Using another answer if you find a solution.

First, I defined the RetryWithDelay function, which starts a repeat after 30 seconds and not immediately.

  private static class RetryWithDelay implements Func1<Observable<? extends Throwable>, Observable<?>> { @Override public Observable<?> call(Observable<? extends Throwable> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Override public Observable<?> call(Throwable throwable) { return Observable.timer(CallBO.REFRESH_INTERVAL_IN_SEC, } }); } } 

which I then used in this observation chain:

 Subscription subscription = Observable.interval(0, REFRESH_INTERVAL, TimeUnit.SECONDS) .concatMap(new Func1<Long, Observable<Response>>() { @Override public Observable<Response> call(Long time) { return webservice.callRetrofitServiceWithRx(parameter); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError(new UpdateErrorAction()) .retryWhen(new RetryWithDelay()) .subscribe(new UpdateSuccessAction()); 
+1
source

All Articles