Reputation: 3393
I'm struggling while figuring how to raise a network error from the data layer to the view layer.
I'm using Room along with RxJava2 and Retrofit2. I'm implementing the repository pattern as local-first, so I query the local data, while fetching from the remote, and updating local data if neccesary. In code, this would be:
public Flowable<List<DEvent>> getAll() {
return db.dEventDataStore().getAll()
.doOnSubscribe(new Consumer<Subscription>() {
@Override
public void accept(final Subscription subscription) throws Exception {
dEventApi.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new MaybeObserver<List<DEvent>>() {
@Override
public void onSubscribe(@NonNull Disposable disposable) {
Timber.d("Remote onSubscribe");
}
@Override
public void onSuccess(@NonNull List<DEvent> dEvents) {
Timber.d("Remote onSuccess!");
db.dEventDataStore().insertAll(dEvents);
}
@Override
public void onError(@NonNull Throwable throwable) {
Timber.d("Remote onError!");
}
@Override
public void onComplete() {
Timber.d("Remote onComplete!");
}
}
);
}
});
}
And in the view layer:
mDisposable.add(repo.getAll()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<DEvent>>() {
@Override
public void accept(List<DEvent> dEvents) throws Exception {
Timber.d("OnNext!!");
mView.showEvents(dEvents);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Timber.e("Error on getting DEvents - " + Log.getStackTraceString(throwable));
}
}));
How can I emit that throwable?
Upvotes: 1
Views: 663
Reputation: 10267
You're not chaining these Observables here - thus an error from the API Observable will not propagate down the stream to the view layer. (moreover I'm not sure how Room operate but you will query it twice for the DB updates)
If I understands correctly, db.dEventDataStore().getAll()
created by Room so this Flowable
is infinite, listen to DB changes and emit any change. so you want to query server, and in case of data update the DB and expect emission from Room's DB Flowable.
in this case, you can do this in parallel using merge
, and the API Maybe, pass through just the errors by ignoring any elements it's emit. in this way the downstream we'll get the data emissions only from Room DB, while still getting server error notifications.
public Flowable<List<DEvent>> getAll() {
return Flowable.merge(
db.dEventDataStore().getAll(),
dEventApi.getAll()
.doAfterSuccess(dEvents -> db.dEventDataStore().insertAll(dEvents))
.ignoreElement()
.toFlowable()
);
}
Upvotes: 1