I have an Observable which implements Error handling in the onErrorResumeNext method.
getMyObservable(params)
.take(1)
.doOnError(e -> {
})
.onErrorResumeNext(throwable -> {
if (throwable.getMessage().contains("401")) {
return getMyObservable(params);
} else {
sendServerCommunicationError();
return Observable.error(throwable);
}
})
.subscribe(result -> {
... }
});
GetMyObservable() returns a web service request from a generated client. The Use Case is: If we receive 401 we may need to refresh the client with a new UserToken. That is why we use the Fallback Observable in onErrorResumeNext() and cannot just use retry.
I have some questions:
Why do I need to implement doOnError?
You don't and doOnError
is not an error handler but a peek into the error channel. You have to implement an error handler in subscribe
:
.subscribe(result -> {
// ...
},
error -> {
// ...
});
How can I achieve that on specific Errors (like 401) I use a fallback Observable with some backoff time and after 5 Times
Use retryWhen
:
Observable.defer(() -> getMyObservable(params))
.retryWhen(errors -> {
AtomicInteger count = new AtomicInteger();
return errors.flatMap(error -> {
if (error.toString().contains("401")) {
int c = count.incrementAndGet();
if (c <= 5) {
return Observable.timer(c, TimeUnit.SECONDS);
}
return Observable.error(new Exception("Failed after 5 retries"));
}
return Observable.error(error);
})
})