RxJava2可观测take抛出不可交付异常
据我所知,RxJava2RxJava2可观测take抛出不可交付异常,java,observable,rx-java2,take,Java,Observable,Rx Java2,Take,据我所知,RxJava2values.take(1)创建了另一个只包含原始可观察对象中一个元素的可观察对象。当异常被take(1)的效果过滤掉时,它不能抛出一个异常 与下面的代码片段一样 Observable<Integer> values = Observable.create(o -> { o.onNext(1); o.onError(new Exception("Oops")); }); values.take(1
values.take(1)
创建了另一个只包含原始可观察对象中一个元素的可观察对象。当异常被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")
);
我的问题是:
create(…)
中运行的代码被停止。为了在这种情况下完全安全,您需要使用o.isDisposed()
来查看可观察对象是否已在下游结束onError
调用丢失。如果可观测对象已经终止,则它要么向下传递,要么作为全局不可传递异常抛出。由可观察对象的创建者“正确”处理可观察对象已结束且发生异常的情况
可观察的
)和消费者(订户
)在流结束时意见不一致。在这种情况下,由于生产者比消费者长寿,因此问题只能在生产者中解决@Kiskae在之前的评论中正确地回答了出现这种异常的原因 此处链接到有关此主题的官方文档: 有时您无法更改此行为,因此有一种方法可以处理此
无法交付的异常。以下是如何避免崩溃和不当行为的代码片段:
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,因此如果您能够消除这些异常,它将是更好的选择。在使用observable.create()时,只需使用tryOnError()。onError()不能保证错误会得到处理。科特林有很多种类型
我在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)
}
}
如果(!o.isDisposed()){o.onError(新异常(“Oops”));}
是正确的处理方法吗?如果在不再观察到可观察对象的情况下该异常丢失是可以接受的,那么是。如果异常真的发生了,那么应该无条件地调用它。不,这需要在生产者中修复,因为使用者已声明自己已终止。如果(!o.isDisposed()){o.onError(new exception(“Oops”);}由于竞争条件的原因不是正确的处理方法(o可以在if条件和onError调用之间进行处理,这不是理论上的,它发生在生产系统中)。另请参阅此讨论:@AbdElraoufSabri一旦引入tryOnError,我就扔掉了该代码。可以在一些旧的提交中找到它,但现在出现tryOnError有什么意义?请参阅FlowableEmitter.tryOnError和2.1.1以来的类似方法。我无法摆脱这些异常,我需要从该RX获得一些数据,但当此错误发生时我无法从Json获取数据。我现在该怎么办(当我在中发出一些可观察的网络请求时。创建我的订户在网络呼叫开始时未被释放,并且在我收到呼叫响应时已被释放。是否有办法在RxJavaPlugins.setErrorHandler
中不获取中断异常
?
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)
}
}