These are chat archives for ReactiveX/RxJava

27th
Jul 2016
Parmeshwar Changulpaye
@changulpaye
Jul 27 2016 09:39
Hello Guys, is there any good tutorial to learn RxJava for android
Mark Paluch
@mp911de
Jul 27 2016 20:35
Hi there. What's the preferred way to deal with exceptions thrown by calling Observer.onNext(…) or Observer.onCompleted(…) (I'm implementing Observable.OnSubscribe)
Sometimes subscribers propagate exceptions to me as element emitter and I've not managed to find a sane way how to deal with exceptions.
Ben Christensen
@benjchristensen
Jul 27 2016 20:36
If onNext is invoking user code that can throw an exception, then you must catch that and pass it via onError.

if onComplete blows up (which is illegal) there is no good way to handle that ... it is undefined behavior. We typically just throw a bad runtime exception. You can possibly try and catch the error and send it via onError, but that's also undefined behavior as the Observer/Subscriber has now received 2 terminal events.

In other words ... onError or onCompleted throwing an exception is illegal and puts everything into an undefined state, and RxJava tries it's best to clean up and expose the thrown Runtime exception.

If onNext fails (also illegal) it can generally be recovered by catching and passing it to onError.

Mark Paluch
@mp911de
Jul 27 2016 20:41
Thanks Ben. I assumed that calling onError after onNext fails would be a good way to deal with that but I was clueless about exceptions in onError/onCompleted
Ben Christensen
@benjchristensen
Jul 27 2016 20:42
yeah it's ugly if those happen ... you can look at the RxJava 'SafeSubscriber' class
it tries to handle them
Mark Paluch
@mp911de
Jul 27 2016 20:42
My question originated from mp911de/lettuce#323
Ben Christensen
@benjchristensen
Jul 27 2016 20:42
and you can see how it throws them up to default Java thread exception handlers
Mark Paluch
@mp911de
Jul 27 2016 20:43
Well, I'm using netty and the last actor that deals with the exception is the channel handler (which is not nice)
Ben Christensen
@benjchristensen
Jul 27 2016 20:43
is it providing you a concrete Observer/Subscriber? Or some other user provided function?
Mark Paluch
@mp911de
Jul 27 2016 20:44
I provide an Observer
Ben Christensen
@benjchristensen
Jul 27 2016 20:45
and what happens inside onComplete that blows up? onComplete and onError should never throw exceptions ... so why are they? That suggests to me either (a) another operator like flatMap or map should be used for this step instead of subscribe, or (b) the Observer should just try/catch and log the errors.
Mark Paluch
@mp911de
Jul 27 2016 20:46
I have no idea what's happening inside the subscribers. From the stack trace I just see that Hystrix is used and runs into some Timeout. So the only thing left I could do is catching the exceptions and logging these
Ben Christensen
@benjchristensen
Jul 27 2016 20:47
but why is that work being done from within an Observer.onComplete?
work should never be done by onComplete.
(other than cleanup with try/catch around it)
Mark Paluch
@mp911de
Jul 27 2016 20:49
Not sure I follow
Ben Christensen
@benjchristensen
Jul 27 2016 20:49
Your question was about onCompleted throwing an exception, right?
Mark Paluch
@mp911de
Jul 27 2016 20:50
Yeah, in particular how to deal with it as producer/emitter
Ben Christensen
@benjchristensen
Jul 27 2016 20:52

Observer.onCompleted should not ever throw. That breaks the contract and puts the system into undefined state. So, it's best to avoid user code that can throw from inside onCompleted.

So what are you doing inside onCompleted? For example, are you using the onCompleted signal to invoke user code?

Mark Paluch
@mp911de
Jul 27 2016 20:53
Ah, ok, now I understand: One of my users uses Hystrix and gRPC to perform some remote RPC work.
Ben Christensen
@benjchristensen
Jul 27 2016 20:54
and it is kicked off from inside onComplete of your Observer?
Mark Paluch
@mp911de
Jul 27 2016 20:54
I don't know what exactly is done in the user code as I'm just providing the Observable in the framework
Exactly
Ben Christensen
@benjchristensen
Jul 27 2016 20:55
yes, so instead of using the Observer to do, I suggest using flatMap (for async), or doOnCompleted (for synchronous side effects) to kick off work
and your final Observer is JUST for cleanup
that way an operator triggers everything in a way that error handling can be done
Mark Paluch
@mp911de
Jul 27 2016 20:56
Ok, I'll pass that details on. Thanks for giving me the certainty that throwing exceptions in onCompleted is illegal
Ben Christensen
@benjchristensen
Jul 27 2016 20:56
This flatMap overload is very powerful, as you can kick off async work (another Observable) on onNext, onError, or onComplete signals: http://reactivex.io/RxJava/javadoc/rx/Observable.html#flatMap(rx.functions.Func1,%20rx.functions.Func1,%20rx.functions.Func0)
yup, no problem
Mark Paluch
@mp911de
Jul 27 2016 20:58
Thanks a lot