我遇到了一个问题,试图处理可能在RxJava2 Observable的订阅服务器内部发生的异常,但是我无法在内部处理。
因此,我需要的是一种建立订户的方法,如果它未能引发异常-RxJava非常渴望获取异常并将其抛出到其他任何地方,但是我希望在其他地方...(这是很好,只要我可以在doOnError中进行处理...)
我知道the spec,但这对我没有帮助。 (并且一个空的ErrorHandler只是会吞下,但不会直接抛出。)
因此,在一些示例中,我尝试引发Exception,我的目标是将其捕获在主要方法的捕获子句中……但是RxJava的ErrorHandler窃取了它。
倒数第二个示例是(我认为很丑)的解决方法-还有其他想法吗?尤其是因为该解决方法不适用于Single。
谢谢!
import io.reactivex.Observable;
import io.reactivex.plugins.RxJavaPlugins;
import java.util.concurrent.atomic.AtomicReference;
public class RxEmittingException {
static Observable<Integer> observable = Observable.just(2, 1, 0);
public static void main(String[] args) {
// without changing this, the behaviour is the same, but it's more readable like this.
RxJavaPlugins.setErrorHandler(t -> System.out.println("[RxErrorHandler] >>> " + t));
/*
My intention is to trigger the catches below printing 'Method failed: ...'!
*/
try {
System.out.println("doSomeDangerousDivision");
doSomeDangerousDivision(4);
System.out.println("~~fail~~\n");
} catch (Throwable e) {
System.err.println("Method failed: " + e);
}
try {
System.out.println("doSomeDangerousDivisionWithErrorHandler");
doSomeDangerousDivisionWithErrorHandler(4);
System.out.println("~~fail~~\n");
} catch (Throwable e) {
System.err.println("Method failed: " + e);
}
try {
System.out.println("doSomeSingleDangerousDivision");
doSomeSingleDangerousDivision(4);
System.out.println("~~fail~~\n");
} catch (Throwable e) {
System.err.println("Method failed: " + e);
}
try {
System.out.println("doSomeSingleDangerousDivisionWithErrorHandler");
doSomeSingleDangerousDivisionWithErrorHandler(4);
System.out.println("~~fail~~\n");
} catch (Throwable e) {
System.err.println("Method failed: " + e);
}
try {
System.out.println("workaround");
workaround(4);
System.out.println("~~fail~~\n");
} catch (Throwable e) {
System.err.println("Method failed: " + e);
}
try {
System.out.println("workaroundSingle");
workaroundSingle(4);
System.out.println("~~fail~~\n");
} catch (Throwable e) {
System.out.println("Method failed: " + e);
}
}
private static void doSomeDangerousDivision(int dividend) throws Throwable {
observable.subscribe(divisor -> System.out.println(dividend + "/" + divisor + "=" + (dividend / divisor)));
}
private static void doSomeDangerousDivisionWithErrorHandler(int dividend) throws Throwable {
observable.subscribe(divisor -> System.out.println(dividend + "/" + divisor + "=" + (dividend / divisor)), throwable -> {
System.out.println("catch and rethrow: " + throwable);
throw new RuntimeException(throwable);
});
}
private static void doSomeSingleDangerousDivision(int dividend) throws Throwable {
observable.lastOrError().subscribe(divisor -> System.out.println(dividend + "/" + divisor + "=" + (dividend / divisor)));
}
private static void doSomeSingleDangerousDivisionWithErrorHandler(int dividend) throws Throwable {
observable.lastOrError()
.subscribe(divisor -> System.out.println(dividend + "/" + divisor + "=" + (dividend / divisor)), throwable -> {
System.out.println("catch and rethrow: " + throwable);
throw new RuntimeException(throwable);
});
}
private static void workaround(int dividend) throws Throwable {
AtomicReference<Throwable> t = new AtomicReference<>();
observable.subscribe(divisor -> System.out.println(dividend + "/" + divisor + "=" + (dividend / divisor)), throwable -> {
System.out.println("catch and assign: " + throwable);
t.set(throwable);
});
System.out.println("Extracted Throwable: " + t.get());
if (t.get() != null) {
throw t.get();
}
}
private static void workaroundSingle(int dividend) throws Throwable {
AtomicReference<Throwable> t = new AtomicReference<>();
observable.lastOrError()
.subscribe(divisor -> System.out.println(dividend + "/" + divisor + "=" + (dividend / divisor)), throwable -> {
System.out.println("catch and assign: " + throwable);
t.set(throwable);
});
System.out.println("Extracted Throwable: " + t.get());
if (t.get() != null) {
throw t.get();
}
}
}
输出为:
doSomeDangerousDivision
4/2=2
4/1=4
[RxErrorHandler] >>> io.reactivex.exceptions.OnErrorNotImplementedException: / by zero
~~fail~~
doSomeDangerousDivisionWithErrorHandler
4/2=2
4/1=4
catch and rethrow: java.lang.ArithmeticException: / by zero
[RxErrorHandler] >>> io.reactivex.exceptions.CompositeException: 2 exceptions occurred.
~~fail~~
doSomeSingleDangerousDivision
[RxErrorHandler] >>> io.reactivex.exceptions.UndeliverableException: java.lang.ArithmeticException: / by zero
~~fail~~
doSomeSingleDangerousDivisionWithErrorHandler
[RxErrorHandler] >>> io.reactivex.exceptions.UndeliverableException: java.lang.ArithmeticException: / by zero
~~fail~~
workaround
4/2=2
4/1=4
catch and assign: java.lang.ArithmeticException: / by zero
Extracted Throwable: java.lang.ArithmeticException: / by zero
Method failed: java.lang.ArithmeticException: / by zero
workaroundSingle
[RxErrorHandler] >>> io.reactivex.exceptions.UndeliverableException:
java.lang.ArithmeticException: / by zero
Extracted Throwable: null
~~fail~~