Morteza Rastgoo
Morteza Rastgoo

Reputation: 6996

"Error in retrofit api call" completes the observable instead of letting the other observable emit items

I have two observable, one gets list from SharedPreferences and the other one gets it from api with retrofit(Ver 1.9.0). I use mergeDelayError to let both observables emit their items even after any error.

    Observable.mergeDelayError(Observable.just(instance.getListFromSharedPrefs()), instance.getListFromApi())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.newThread())
            .subscribe(new Observer<List<Item>>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    Log.d("ItemList", "Error: " + e.toString());

                }

                @Override
                public void onNext(List<Item> Items) {
                    Log.d("ItemList", "ItemsFetched:" + Items.toString());
                    if (mAdapter != null) {
                        mAdapter.setItems(Items);
                    }
                }
            });

But when there is an error with retrofit api call(i.e. No internet connection), the whole process is completed after onError and it can not get the list from SharedPreferences.

This is the log when app first starts:

12-30 15:49:23.044 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:49:23.189 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:49:23.409 12197-12197/com.me.android D/itemList: Error: retrofit.RetrofitError

But when i close the app and reopen it everything works fine:

12-30 15:51:27.396 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.426 12197-12197/com.me.android D/itemList: itemsFetched:[com.me.android.model.entity.item.item@676ffe9]
12-30 15:51:27.438 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.618 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.700 12197-12197/com.me.android D/itemList: SharedPrefsandroid.app.SharedPreferencesImpl@9b59793
12-30 15:51:27.772 12197-12197/com.me.android D/itemList: Error: retrofit.RetrofitError

Upvotes: 2

Views: 556

Answers (2)

akarnokd
akarnokd

Reputation: 70017

The problem is likely the observeOn which let's onError cut ahead of any value, no matter of the mergeDelayError delaying the error after the value.

There is a PR waiting for approval that lets observeOn also delay errors, but for now, you can apply materialize before observeOn and dematerialize just after it.

Edit Example:

Observable.mergeDelayError(
    Observable.just(
        instance.getListFromSharedPrefs()), instance.getListFromApi())
    .materialize()
    .observeOn(AndroidSchedulers.mainThread())
    .dematerialize()
    .subscribeOn(Schedulers.newThread())
    .subscribe(...);

Upvotes: 4

LordRaydenMK
LordRaydenMK

Reputation: 13321

mergeDelayError does not remove the error, it just delays it unit the other observables finish emitting items.

You might wanna try using onErrorReturn eg:

instance.getListFromSharedPrefs().mergeWith(instance.getListFromApi().onErrorReturn(Observable.empty())

to ignore a network in the API call.

Upvotes: 2

Related Questions