RxJava doOnError vs onError
Asked Answered
L

2

8

I am try to use the following code

initLocalSettingsIfNeed()
                            .andThen(initGlobalSettingsIfNeed(configuration))
                            .doOnComplete(callback::onSuccess)
                            .doOnError(throwable -> callback.onError(throwable.getLocalizedMessage()))
                            .subscribe();

But I have exception

The exception was not handled due to missing onError handler in the subscribe() method call.

I guess I am not using this methods correctly, I thought can replace doOnComplete doOnError with observer inside subscribe() method, I am wrong?

Lakshmi answered 16/4, 2019 at 12:34 Comment(3)
that's the expected behaviour. Try with onErrorComplete, if you want to swallow the errorTahiti
No, i need to handle the error, this approach is wrong because doOnComplete() return new Single?Lakshmi
no it is not because of that. doOnError in not a replacement for onErrorTahiti
S
9

Regarding your original question, you have to know that doOnError is not a replacement of onError:

Actually there’s one key difference between them. doOnError() basically only triggers its callback, then passes down the encountered errors to the down stream. So if the whole stream is subscribed without the onError callback in subscribe(), your app will crash by OnErrorNotImplementedException.

The onError callback in subscribe() in the other hand does consume the errors. That means, it will catch the errors, and let you handle them without re-throwing the errors by itself.

About the warning you mention in one comment:

This approach is working, but i have warning 'the result of subscribe not used', as i know this need to be disposed automatically when onError or onComplete is called, is there way to avoid this warning? – Pavel Poley

A good approach is that your methods inside your Repository return a Observable, and then you can subscribe to them in your ViewModel. Then, in every ViewModel class you can have a member variable with a CompositeDisposable where you can add the disposable of each subscription to the Observables returned by your repository. Finally, you should override the onCleared method to dispose all the disposables stored in the CompositeDisposable.

public class MyViewModel extends ViewModel {

    private MyRepository myRepository;
    private final CompositeDisposable disposables;

    @Inject
    public MyViewModel(MyRepository myRepository) {
        ...
        this.myRepository = myRepository;
        disposables = new CompositeDisposable();
        ...
    }

    public void callObservableInRepository() {
         disposables.add(myRepository.myObservable()
                              .subscribe(onSuccess -> {...} , onError -> {...}));
    }

    @Override
    protected void onCleared() {
        disposables.clear();
    }

}
Spermine answered 16/4, 2019 at 13:22 Comment(2)
the blog link is deadThrown
@Thrown probably taken down by the person writing it, but the relevant information is quoted in the answerSpermine
T
3

try this

initLocalSettingsIfNeed()
    .andThen(initGlobalSettingsIfNeed(configuration))
    .subscribe({completed->
        callback.onSuccess()
    },{throwable->
        callback.onError(throwable.getLocalizedMessage())
    })
Tallula answered 16/4, 2019 at 12:44 Comment(7)
This approach is working, but i have warning 'the result of subscribe not used', as i know this need to be disposed automatically when onError or onComplete is called, is there way to avoid this warning?Lakshmi
you can add it for example to CompositeDisposable() and dispose it after it is not needed anymore. Eg disposables.add(wrapped above code) and then disposables.dispose()Tallula
but i am not using it in activity, i am using it in repositories without lifecycleLakshmi
Repostory usage logic should be handled in Model when using MVP or ViewModel when using MVVMTallula
so it is not safe not to use result of disposable? event if it simple request onComplete onError?Lakshmi
in my case i using few repositories in top level component to encapsulate some async requests, so in this case i need to make the top level component lifecycle aware?Lakshmi
It depends on what kind of Observable are you using, if it is for example Single is completely safe to use it without disposing because it is emitting only one time. That what I am using for repositoryTallula

© 2022 - 2024 — McMap. All rights reserved.