TL;DR
I think that flatMap
combined with switchMap
might not terminate the stream correctly, thus UndeliverableException
happens. How can I fix this?
The Structure
I'm making a little bit complex stream -- combined with flatMap
and switchMap
-- like below, in RxKotlin (RxJava 3):
someObservable
.flatMapMaybe {
if (matchCondition(it)) Maybe.just(it)
else Maybe.never()
}.flatMapSingle {
procedureMiddle(it) // Inconsistent-time-consuming Single
}.switchMap {
procedureLater(it)
}.doOnError {
dealWithError(e)
}.retry()
.subscribeBy(
// ...
)
The procedureMiddle
inside flatMapSingle
has a chance of returning Error in the end.
The Exception
It turns out that sometimes the error from procedureMiddle
might jump out of structure, not being ignored by retry
, nor dealt in dealWithError
in doOnError
:
W/System.err: io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | my.custom.app.CustomException
// traces indicates that the Exception is thrown from inside procedureMiddle
The Question
In fact the UndeliverableException
doesn't really cause crash, but it's a little bit annoying for me --especially it looks like a situation I need to handle. However I thought the structure is correctly written? So here's my question:
- Does
switchMap
really (correctly) terminate the last stream fromflatMap
? (And can be used to preventUndeliverableException
?) - If so, at which part of code I should adjust? If not so, how could I prevent the exceptions along with my structure? (I want to concat
procedureLater
afterprocedureMiddle
, and keep only latest one)
Any suggestion or explanation would be helpful.