java 解决故意弄得错误_RxJava中的错误处理

在RxJava中我们可以很方便地处理异常,只要加上onError即可。

不过,如果异常发生在操作符内部,比如flatMap,那我们怎么把这个异常传递给onError呢。

Checked异常和Unchecked异常

Checked异常必须被显式地捕获或者传递,而unchecked异常则可以不必捕获或抛出。

Checked异常继承java.lang.Exception类。Unchecked异常继承自java.lang.RuntimeException类。

Unchecked异常

一般情况下,unchecked异常会自动传递给onError。例如以下代码可以打印出“Error!”。

Observable.just("Hello!")

.map(input -> {throw new RuntimeException();})

.subscribe(

System.out::println,

error -> System.out.println("Error!")

);

也有例外的情况,那就是... 那些非常严重的错误,以致于RxJava都不能继续运行了。比如StackOverflowError,这些异常被认为是致命的,对它们来说,调用onError毫无意义,并没什么用。你可以用Exceptions.throwIfFatal来过滤掉这些致命的异常并重新抛出,不发射关于它们的通知。

Checked异常

尽管RxJava有自己的异常处理机制,不过Checked异常还是必须由你的代码来处理,也就是说,还是要自己加try-catch。

假设我们用到这样方法:

String transform(String input) throws IOException;

我们可以把Checked异常转换为Unchecked异常,像这样:

Observable.just("Hello!")

.map(input -> {

try {

return transform(input);

} catch (Throwable t) {

throw Exceptions.propagate(t);

}

});

Exceptions.propagate()只是简单地做了这样一件事:如果异常是Checked异常,那就把它包装成Unchecked异常。

而对于像flatMap这样返回Observable对象的操作,可以直接返回Observable.error()。

Observable.just("Hello!")

.flatMap(input -> {

try {

return Observable.just(transform(input));

} catch (Throwable t) {

return Observable.error(t);

}

});

异常的屏蔽

很多RxJava初学者都犯了一个错误,过度地使用onError,其实onError应该在数据无法继续处理下去时才使用。例如,在使用Retrofit 1的时候,响应的状态码为非200的结果调用onError,这样,我们在处理非200的响应结果时就会变得十分麻烦。这个问题在Retrofit 2已经解决了,现在可以通过Observable>和Observable>,来处理onNext中的非200的结果返回。

也就是说,通常,你可以在发生错误的时候给onNext一个错误的标识,然后直接在onNext中处理问题,而不是跳过代码进入onError,这样还是可以不中断你的数据流,继续运行你的代码。

如何屏蔽异常而不把异常抛给onError,以下有两种选择:

onErrorReturn(),在遇到错误时发射一个特定的数据

onErrorResumeNext(),在遇到错误时发射一个数据序列

Observable.just("Request data...")

.map(this::dangerousOperation)

.onErrorReturn(error -> "Empty result");

当dangerousOperation产生异常时,不会触发onError,而是返回字符串"Empty result"。

当上游的Observable观察到异常通知(onError)时,通过onErrorReturn或onErrorResumeNext来把onError转换成与下游序列有所区分的数据。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值