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 | onError
的 Single
。因此,如果 onSuccess
崩溃,它无法在同一个观察者上调用 onError
。
相比之下,Observable
具有协议 onNext* (onError|onComplete)?
,因此允许崩溃 onNext
调用 onError
。
你有几个选择 Single
:
- 在订阅前将其转换为
Observable
,
- 在不可靠的
onSuccess
处理程序中添加 try-catch,
- 在较早的运算符中执行 mapping/transformation,例如
map
,因此最终消费者不太可能崩溃。
该异常最终未得到处理,并在 Crashlytics 中被报告为非致命异常,因此不在我们的关注范围内 用户看到了一个不希望出现的空白屏幕 崩溃会更好,因为 fail-fast 是首选
理想情况下,我希望 onError
消费者被触发,这就是我处理错误的地方,例如每个流
然而,
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 | onError
的 Single
。因此,如果 onSuccess
崩溃,它无法在同一个观察者上调用 onError
。
相比之下,Observable
具有协议 onNext* (onError|onComplete)?
,因此允许崩溃 onNext
调用 onError
。
你有几个选择 Single
:
- 在订阅前将其转换为
Observable
, - 在不可靠的
onSuccess
处理程序中添加 try-catch, - 在较早的运算符中执行 mapping/transformation,例如
map
,因此最终消费者不太可能崩溃。