据我所知,RxJava2 values.take(1)
创建了另一个Observable,它只包含原始Observable中的一个元素。哪个绝不能抛出异常,因为它被take(1)
的影响过滤掉了,因为它发生了第二次。
与以下代码段
中一样 Observable<Integer> values = Observable.create(o -> {
o.onNext(1);
o.onError(new Exception("Oops"));
});
values.take(1)
.subscribe(
System.out::println,
e -> System.out.println("Error: " + e.getMessage()),
() -> System.out.println("Completed")
);
1
Completed
io.reactivex.exceptions.UndeliverableException: java.lang.Exception: Oops
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:83)
at ch02.lambda$main$0(ch02.java:28)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:10841)
at io.reactivex.internal.operators.observable.ObservableTake.subscribeActual(ObservableTake.java:30)
at io.reactivex.Observable.subscribe(Observable.java:10841)
at io.reactivex.Observable.subscribe(Observable.java:10827)
at io.reactivex.Observable.subscribe(Observable.java:10787)
at ch02.main(ch02.java:32)
Caused by: java.lang.Exception: Oops
... 8 more
Exception in thread "main" io.reactivex.exceptions.UndeliverableException: java.lang.Exception: Oops
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:83)
at ch02.lambda$main$0(ch02.java:28)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:10841)
at io.reactivex.internal.operators.observable.ObservableTake.subscribeActual(ObservableTake.java:30)
at io.reactivex.Observable.subscribe(Observable.java:10841)
at io.reactivex.Observable.subscribe(Observable.java:10827)
at io.reactivex.Observable.subscribe(Observable.java:10787)
at ch02.main(ch02.java:32)
Caused by: java.lang.Exception: Oops
... 8 more
答案 0 :(得分:44)
create(...)
内运行的代码已停止。要在这种情况下完全安全,您需要使用o.isDisposed()
来查看observable是否已经在下游结束。onError
调用丢失,因此存在异常。如果observable已经终止,它将作为全局UndeliverableException
传递到下游或抛出。由Observable的创建者“正确”处理observable已经结束并发生异常的情况。Observable
)和消费者(Subscriber
)在流结束时不一致。由于生产者在这种情况下比消费者寿命长,因此问题只能在生产者中解决。答案 1 :(得分:7)
@Kiskae在之前的评论中正确回答了可能发生此类异常的原因。
此处指向此主题的官方文档的链接:RxJava2-wiki。
有时您无法更改此行为,因此有一种方法可以处理此UndeliverableException
。以下是如何避免崩溃和错误行为的代码片段:
RxJavaPlugins.setErrorHandler(e -> {
if (e instanceof UndeliverableException) {
e = e.getCause();
}
if ((e instanceof IOException) || (e instanceof SocketException)) {
// fine, irrelevant network problem or API that throws on cancellation
return;
}
if (e instanceof InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
return;
}
if ((e instanceof NullPointerException) || (e instanceof IllegalArgumentException)) {
// that's likely a bug in the application
Thread.currentThread().getUncaughtExceptionHandler()
.handleException(Thread.currentThread(), e);
return;
}
if (e instanceof IllegalStateException) {
// that's a bug in RxJava or in a custom operator
Thread.currentThread().getUncaughtExceptionHandler()
.handleException(Thread.currentThread(), e);
return;
}
Log.warning("Undeliverable exception received, not sure what to do", e);
});
此代码取自上面的链接。
重要提示。这种方法将全局错误处理程序设置为RxJava,因此如果您能够摆脱这些异常 - 那将是更好的选择。
答案 2 :(得分:0)
使用observable.create()时,只需要使用tryOnError()。 onError()不能保证错误会得到处理。有error handling operators种HERE
答案 3 :(得分:0)
科特林
我通过MainActivity onCreate方法对此进行了校准
private fun initRxErrorHandler(){
RxJavaPlugins.setErrorHandler { throwable ->
if (throwable is UndeliverableException) {
throwable.cause?.let {
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), it)
return@setErrorHandler
}
}
if (throwable is IOException || throwable is SocketException) {
// fine, irrelevant network problem or API that throws on cancellation
return@setErrorHandler
}
if (throwable is InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
return@setErrorHandler
}
if (throwable is NullPointerException || throwable is IllegalArgumentException) {
// that's likely a bug in the application
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), throwable)
return@setErrorHandler
}
if (throwable is IllegalStateException) {
// that's a bug in RxJava or in a custom operator
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), throwable)
return@setErrorHandler
}
Log.w("Undeliverable exception", throwable)
}
}