The exception ended up not handled and was reported as a non-fatal in Crashlytics, hence fell off our radar User saw a blank screen which is not desirable A crash would have been better, for fail-fast is preferred
Ideally, I'd like to the onError
consumer to be trigger, that's where I handle the error e.g. shows error UI for every stream
However,
fun main() {
Single.just(listOf("efaewf"))
.subscribe({
println("result is ${it[1]}")
}, {
println("handling exception")
it.printStackTrace()
})
}
shows that onError
consumer is not working
io.reactivex.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 | java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:65)
at io.reactivex.internal.operators.single.SingleJust.subscribeActual(SingleJust.java:30)
at io.reactivex.Single.subscribe(Single.java:3603)
at io.reactivex.Single.subscribe(Single.java:3589)
at com.coffeemeetsbagel.DummyKt.main(Dummy.kt:7)
at com.coffeemeetsbagel.DummyKt.main(Dummy.kt)
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.Collections$SingletonList.get(Collections.java:4817)
at com.coffeemeetsbagel.DummyKt$main$1.accept(Dummy.kt:8)
at com.coffeemeetsbagel.DummyKt$main$1.accept(Dummy.kt)
at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:62)
... 5 more
Exception in thread "main" io.reactivex.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 | java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:65)
at io.reactivex.internal.operators.single.SingleJust.subscribeActual(SingleJust.java:30)
at io.reactivex.Single.subscribe(Single.java:3603)
at io.reactivex.Single.subscribe(Single.java:3589)
at com.coffeemeetsbagel.DummyKt.main(Dummy.kt:7)
at com.coffeemeetsbagel.DummyKt.main(Dummy.kt)
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.Collections$SingletonList.get(Collections.java:4817)
at com.coffeemeetsbagel.DummyKt$main$1.accept(Dummy.kt:8)
at com.coffeemeetsbagel.DummyKt$main$1.accept(Dummy.kt)
at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:62)
... 5 more
I've read the docs here but don't comprehend fully
I could totally add if {} else {}
or try {} catch {}
to onSuccess
consumer but it feels like code smell
Am I wrong, is if else/ try catch the best and/ or intended way to handle exceptions in onSuccess
?
You are using Single
which has the protocol onSuccess | onError
. So if onSuccess
crashes, it can't invoke onError
on the same observer.
In contrast, Observable
has the protocol onNext* (onError|onComplete)?
so a crashing onNext
is then allowed to invoke onError
.
You have a few options with Single
:
Observable
before the subscribe,onSuccess
handler,map
, so the end consumer is unlikely to crash.