Reputation: 4701
I've been playing around with retryWhen() method and i noticed that if you use filter() inside retryWhen() and if filter() fails there's no callback executed not even onCompleted(). Can you please explain to me why is this happening? Thanks in advance.
The working case:
Observable.error(new RuntimeException())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retryWhen(errors -> errors
.filter(throwable -> throwable instanceof RuntimeException)
.zipWith(Observable.range(1, 3), (throwable, retryCount) -> {
Log.i("lol", "retry " + retryCount);
return retryCount;
}))
.subscribe(e -> Log.i("lol", "onNext"), throwable -> Log.i("lol", "onError"), () -> Log.i("lol", "onCompleted"));
The working output:
I: retry 1
I: retry 2
I: retry 3
I: onCompleted
But when i changed the filter with filter(throwable -> throwable instanceof IOException)
the observable is like in a frozen state. No callback fired.
Observable.error(new RuntimeException())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retryWhen(errors -> errors
.filter(throwable -> throwable instanceof IOException)
.zipWith(Observable.range(1, 3), (throwable, retryCount) -> {
Log.i("lol", "retry " + retryCount);
return retryCount;
}))
.subscribe(e -> Log.i("lol", "onNext"), throwable -> Log.i("lol", "onError"), () -> Log.i("lol", "onCompleted"));
Upvotes: 2
Views: 2152
Reputation: 8227
You don't want to use filter()
inside the retryWhen()
operator. Instead, use an if
statement or switch
statement to ensure you have complete coverage of all cases.
The way that retryWhen()
works is that it creates an observable and invoking the function with it. When it catches the throwable in its onError()
method, it emits that throwable into the observable and waits for the result. If it gets no result, such as when a throwable is filtered, it will wait forever.
Upvotes: 4