doOnError 没有捕获异常

问题描述 投票:0回答:2

我刚刚开始使用 RxJava,但也许还没有点击。

1.

Integer[] items = {1, 2, 3, 0, 0, 4, 5, 6, 1};
Observable.from(items)
        .map(this::invert)
        .subscribe(i -> Log.d(LOG_TAG, "Inverted: " + i), t -> Log.d(LOG_TAG, "Error: " + t.getMessage()));

2.

Integer[] items = {1, 2, 3, 0, 0, 4, 5, 6, 1};
Observable.from(items)
        .map(this::invert)
        .doOnError(t -> Log.d(LOG_TAG, "Error: " + t.getMessage()))
        .doOnNext(i -> Log.d(LOG_TAG, "Inverted: " + i))
        .subscribe();

invert
功能:

int invert(int i) {
    return 1 / i;
}

第一个正常执行,当抛出异常时执行

onError
。但另一方面,第二个不起作用,所以异常一直抛到调用方法。

这两段代码有什么区别?

java android rx-java rx-android
2个回答
24
投票

请记住,

.doOnError()
捕获异常,用它做一些事情然后重新抛出它。如果您想要不同的行为,请使用
.onError*
方法之一。

现在,异常没有传播到#1 中的调用者但在#2 中传播的原因是您在#1 中提供了错误处理程序,但没有在#2 中提供,在这种情况下,默认情况下传播例外。


0
投票

完成上面塔索斯的回答

RxJava 不允许异常“冒泡”。如果一个异常逃脱了执行链而没有被捕获,而不是将它传播到你的调用代码,Rx 将捕获它并记录一条错误消息,如

onErrorDropped reactor.core.Exceptions$ErrorCallbackNotImplemented: <your exeception and message here>
。见https://github.com/reactor/reactor-core/issues/2677

正如塔索斯所说,异常是从

doOnError()
重新抛出的。所以如果你使用这个功能来处理错误,你应该从链中删除错误,就像这样

Observable.from(items)
    .map(this::invert)
    .doOnError(t -> Log.d(LOG_TAG, "Error: " + t.getMessage()))
    .onErrorResume(e -> Mono.empty()) // Replace Mono.empty() with an alternative function if you want some behavior on error
    .doOnNext(i -> Log.d(LOG_TAG, "Inverted: " + i))
    .subscribe();

参见 https://nickolasfisher.com/blog/Making-Sense-of-Mono-Error-Handling-in-Spring-Boot-WebfluxProject-Reactor 有关 onErrorX 工作原理的更多详细信息

© www.soinside.com 2019 - 2024. All rights reserved.