RxJava2 using retryWhen with filter

2.1k Views Asked by At

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"));
1

There are 1 best solutions below

2
On BEST ANSWER

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.