Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error handling in toBlocking()

I'm refactoring an app to reactive paradigm using RxJava. I'm doing it step by step so I need to use toBlocking() in some cases in order to respect the interfaces, for the moment. How can I handle an error when use toBlocking()?

Before, I had something like this:

public List<Employee> getEmployees() {
    try {
        return repository.getEmployees();
    } catch(Exception e) {
        throw new MyCustomException();
    } 
}

Now, the repository has a reactive interface (returns Observable<List<Employee>>), so I'm doing this:

public List<Employee> getEmployees() {
    return repository.getEmployees().toBlocking().single(); 
}

Subscription to repository.getEmployees() may return an error Observable. My question is: how can I handle this error keeping it blocking?

I have found out a method singleOrDefault(), but something like singleOrThrow(new MyCustomException()) would be nice.

like image 325
Héctor Avatar asked Mar 14 '17 12:03

Héctor


People also ask

How will you handle error in RxJava?

RxJava Error HandlingIf Consumer didn't handle error in Observer callback, then that error is sent to a global error handler (which in case of Android crashes the app by default). NOTE: some errors which happen inside stream can go directly to global error handler e.g. in cases when the stream is already disposed.

What is onErrorResumeNext RxJava?

Similar to onErrorReturn() and onErrorReturnItem() , onErrorResumeNext() is very similar. The only difference is that it accepts another Observable as a parameter to emit potentially multiple values, not a single value, in the event of an exception.

What is doOnError?

doOnError. doOnError is used to add side effect behaviour triggered just before the error is sent downstream, as you can see below this is different from onErrorResume as the error will be propagated to subsequent operators (you can for example use it for instrumentation purposes).


1 Answers

You can't do that, you will need to wrap it with try/catch block, toBlocking() transform the Observable to BlockingObservable which is not exactly reactive block, more like fancy collection, it's now lack the power of composing Observables, operators, controlling the thread/parallelism, and the basic construct of async API, which has error handling built in, (onError())

That what the docs stated about BlockingObservable:

It can be useful for testing and demo purposes, but is generally inappropriate for production applications (if you think you need to use a BlockingObservable this is usually a sign that you should rethink your design).

So, what is the point to act with blocking observable? if you can't change the interface to Observable, then you probably missing all the point of using Rx and Observable, which is (at ideal) to abstract out every event based operation in the system, and then being able to use the power of Operators/Composition/Async management and construct event streams in your system.
If you just wrap some API operation with Observable and then return it back to non-reactive world, then the consumer of the API can't enjoy all the aforementioned benefits of Rx.
So, I think you should reconsider what is the purpose of doing that, and what is your final goal, you can consider replacing to Reactive approach in few places in your system for start.

like image 99
yosriz Avatar answered Oct 08 '22 20:10

yosriz