RxJava Objects and Error Handling
I am trying to achieve the same behavior as for the event bus. Suitable for my requirements PublishSubject
.
The object emits elements that represent the result of some global operation that may succeed or fail if an exception occurs. I cannot use onNext()
for success events and onError()
on Throwable
on error, since after the call the onError()
subject is terminated and any future subscribers will not receive any outliers except onError()
one.
Right now the way I see it, I need to create a class that represents the event, and optionally reference it on Throwable
error. This, however, seems unwise as it would need to handle errors internally onNext()
.
How would you do it?
source to share
Generating generic class transfer events is the way to go. Let's say we call it the ResponseOrError class, it should contain basically two fields
private T data;
private Throwable error;
and two simple factory methods:
public static <T> ResponseOrError<T> fromError(Throwable throwable) {
return new ResponseOrError<>(throwable);
}
public static <T> ResponseOrError<T> fromData(T data) {
return new ResponseOrError<>(data);
}
to remove any boilerplate code, you can provide a Transformer to create an Observerable ResponseOrError.
public static <T> Observable.Transformer<T, ResponseOrError<T>> toResponseOrErrorObservable() {
return new Observable.Transformer<T, ResponseOrError<T>>() {
@Override
public Observable<ResponseOrError<T>> call(final Observable<T> observable) {
return observable
.map(new Func1<T, ResponseOrError<T>>() {
@Override
public ResponseOrError<T> call(final T t) {
return ResponseOrError.fromData(t);
}
})
.onErrorResumeNext(new Func1<Throwable, Observable<? extends ResponseOrError<T>>>() {
@Override
public Observable<? extends ResponseOrError<T>> call(final Throwable throwable) {
return Observable.just(ResponseOrError.<T>fromError(throwable));
}
});
}
};
}
then you can use it like this:
final Observable<ResponseOrError<ImportantData>> compose = mNetworkService
.getImportantData()
.compose(ResponseOrError.<ImportantData>toResponseOrErrorObservable());
and now you can easily display the result depending on success or failure, or even provide another transformed transformer displayed by Observable <T> instead of observable <ResponseOrError <T ->
source to share