RxJava UndeliverableException 如何处理onSuccess 消费异常?

RxJava UndeliverableException how to handle onSuccess consumer exception?

该异常最终未得到处理,并在 Crashlytics 中被报告为非致命异常,因此不在我们的关注范围内 用户看到了一个不希望出现的空白屏幕 崩溃会更好,因为 fail-fast 是首选

理想情况下,我希望 onError 消费者被触发,这就是我处理错误的地方,例如每个流

显示错误 UI

然而,

fun main() {
    Single.just(listOf("efaewf"))
            .subscribe({
                println("result is ${it[1]}")
            }, {
                println("handling exception")
                it.printStackTrace()
            })
}

表明 onError 消费者没有工作

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.accept(Dummy.kt:8)
    at com.coffeemeetsbagel.DummyKt$main.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.accept(Dummy.kt:8)
    at com.coffeemeetsbagel.DummyKt$main.accept(Dummy.kt)
    at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:62)
    ... 5 more

我读过the docs here但没有完全理解

我完全可以将 if {} else {}try {} catch {} 添加到 onSuccess 消费者,但感觉代码有味道

我错了吗,if else/try catch 是在 onSuccess 中处理异常的最佳和/或预期方式吗?

您正在使用具有协议 onSuccess | onErrorSingle。因此,如果 onSuccess 崩溃,它无法在同一个观察者上调用 onError

相比之下,Observable 具有协议 onNext* (onError|onComplete)?,因此允许崩溃 onNext 调用 onError

你有几个选择 Single:

  • 在订阅前将其转换为Observable
  • 在不可靠的 onSuccess 处理程序中添加 try-catch,
  • 在较早的运算符中执行 mapping/transformation,例如 map,因此最终消费者不太可能崩溃。