Search code examples
javaandroidretrofitrx-javarx-java2

How do I make RxJava call onErrorReturn() and still execute onError()


When I call the Retrofit method GetTodoRepository.fetchTodo() from MainViewModel and call ends in a failure or any non-success result, I would like to let RxJava to both do onErrorReturn() and onError() so I can return a cached object in that case, but still notify MainViewModel that an error happend, so I can show error-related UI views. How do I archive this?

The current code shows how I intended to handle it.

MainViewModel

public class MainViewModel extends ViewModel

    public LiveData<String> getTodo() {
    getTodoRepository.fetchTodo().subscribe(new SingleObserver<String>() {
        @Override
        public void onSubscribe(Disposable d) {
        }

        @Override
        public void onSuccess(String s) {
            showProgressAnim.setValue(false);
            todo.setValue(s);
        }

        @Override
        public void onError(Throwable e) {
            showProgressAnim.setValue(false);
            errorMsg.setValue(e.getMessage());
        }
     });
        return todo;
    }
}

GetTodoRepository

public class GetTodoRepository {

    public Single<String> fetchTodo() {
        return retrofit.create(TodoApi.class)
            .getTodo()
            .doOnSuccess(s -> cacheManager.saveTodo(s))
            .onErrorReturn(throwable -> cacheManager.getTodo())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
    }
}

Solution

  • You can't have both signal types with a Single but you can turn fetchTodo() into Observable and emit the cached item and the error together:

    fetchTodo()
    .toObservable()
    .onErrorResumeNext(error -> 
         Observable.just(cached)
         .concatWith(Observable.error(error))
    )