首页 > 解决方案 > RxJava UndeliverableException如何处理onSuccess消费者异常?

问题描述

异常最终没有被处理,并且在 Crashlytics 中被报告为非致命的,因此从我们的雷达中消失了用户看到了一个不可取的空白屏幕崩溃会更好,因为首选快速失败

理想情况下,我希望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$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

我已经阅读了这里的文档,但没有完全理解

我可以完全添加if {} else {}或添加try {} catch {}onSuccess消费者,但感觉就像代码气味

我错了吗,如果 else/try 捕捉到处理异常的最佳和/或预期方法onSuccess吗?

标签: kotlinrx-javarx-java2

解决方案


您正在使用Single哪个具有协议onSuccess | onError。所以如果onSuccess崩溃,它不能onError在同一个观察者上调用。

相反,Observable有协议,因此允许调用onNext* (onError|onComplete)?崩溃。onNextonError

你有几个选择Single

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

推荐阅读