在 RXJava 中使用 Actions 订阅时如何处理异常

How to handle exceptions when subscribing with Actions in RXJava

这是一个简单的例子:

Completable c = Completable.create(new CompletableOnSubscribe() {
    @Override
    public void subscribe(@NonNull CompletableEmitter e) throws Exception {
        throw new Exception("Oh No!");
    }
});

try {
    c.subscribe(new Action() {
        @Override
        public void run() throws Exception {
            Timber.v("It's ok");
        }
    });
}
catch (Exception e) {
    e.printStackTrace();
    Timber.v("Error");
}

在这种情况下,我本以为异常会被捕获,但它会导致应用程序崩溃。那么我们应该如何处理内部class方法抛出的异常呢?

我知道我们可以通过订阅 CompletableObserver 来以不同的方式处理这个问题,但这增加了我想避免的额外冗长,我觉得必须有一种方法来处理这种异常 other Action 消费者不会很有用。

存在用于处理错误的重载:

c.subscribe(new Action() {
    @Override
    public void run() throws Exception {
        Timber.v("It's ok");
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable e) {
        e.printStackTrace();
        Timber.v("Error");
    }
});

首先RxJava已经有了捕捉异常的机制,但是你需要实现onErrorAction.

看看下面的代码:

Completable c = Completable.create(new CompletableOnSubscribe() {
    @Override 
    public void subscribe(@NonNull CompletableEmitter e) throws Exception {
        throw new Exception("Oh No!");
    } 
})

c.subscribe(new Action() { 
    @Override 
    public void run() throws Exception {
        Timber.v("It's ok"); 
    } 
}, new Consumer<Throwable>() {  // Second argument is onError Action
    @Override 
    public void accept(Throwable e) { 
        // Handle you exception here.
        Timber.v("Error"); 
    } 
}); 

让我们来看看为什么即使您将所有内容都放入 try-catch 中,您的代码也无法捕获异常,因为抛出的异常是 RuntimeException class 的实例,而您正在捕获的实例Exception class。 尝试使用 RuntimeException,抛出的异常应该会被捕获。

但这不是捕获异常的理想方法,而是使用上面代码段中描述的 onError 操作。如果您的代码抛出运行时异常,则使用 Observables 中的 try-catch 将其转换为 Exception

希望对您有所帮助。