RxJava中的错误处理

作者: 东东东鲁 | 来源:发表于2016-03-31 21:18 被阅读10532次

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

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

Checked异常和Unchecked异常

  • Checked异常必须被显式地捕获或者传递,而unchecked异常则可以不必捕获或抛出。
  • Checked异常继承java.lang.Exception类。Unchecked异常继承自java.lang.RuntimeException类。

Unchecked异常

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

Observable.just("Hello!")
          .map(input -> {throw new RuntimeException();})
          .subscribe(
              System.out::println,
              error -> System.out.println("Error!")
          );

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

Checked异常

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

假设我们用到这样方法:

String transform(String input) throws IOException;  

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

Observable.just("Hello!")
    .map(input -> {
        try {
            return transform(input);
        } catch (Throwable t) {
            throw Exceptions.propagate(t);
        }
    });

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

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

Observable.just("Hello!")
    .flatMap(input -> {
        try {
            return Observable.just(transform(input));
        } catch (Throwable t) {
            return Observable.error(t);
        }
    });

异常的屏蔽

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

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

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

  • <code>onErrorReturn()</code>,在遇到错误时发射一个特定的数据
  • <code>onErrorResumeNext()</code>,在遇到错误时发射一个数据序列
Observable.just("Request data...")
    .map(this::dangerousOperation)
    .onErrorReturn(error -> "Empty result");

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

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

参考

Error handling in RxJava
RxDocs

相关文章

  • Rxjava错误处理

    在RxJava中错误处理的最佳方式是什么? 原文地址:https://rongi.github.io/kotlin...

  • RxJava中的错误处理

    在RxJava中我们可以很方便地处理异常,只要加上 onError 即可。 不过,如果异常发生在操作符内部,比如 ...

  • RxJava基础五-错误处理操作符

    此篇内容均是来自书籍《RxJava响应式编程》李衍顺 著 3.5 错误处理操作符 RxJava对错误的处理很方便,...

  • RxJava的错误处理一-retry

    RxJava的错误处理主要分为两类,retry系列以及onErrorRetrun系列。retry系列是当错误的时候...

  • RxJava 错误处理

    Rx中, 很容易处理异常, 整个链式调用过程中,如果异常不做处理, 最后都会交给onError; 不要过渡的依赖o...

  • RxJava错误处理与线程并发

    错误处理 Rxjava为链式调用,事件从源头流到尽头。一个源头链条中发生异常或者Observable.error(...

  • RxJava(二)错误处理

    上一篇讲到RxJava的基本用法,但只是正常使用还是不够的,我们在进行网络操作时难免遇到错误的情况,那遇到这些情况...

  • RxJava全局错误处理

    在RxJava中rx.pluginsRxJavaPlugins这个类是用来处理发生的错误的,在RxJava的源码中...

  • RxJava 操作符(创建、变换)

    概述 RxJava 操作符的类型有多种,如:创建、变换、过滤、组合、错误处理、辅助、条件和布尔操作符等,还有许多延...

  • Rust语言教程(6) - 错误处理和可选值

    Rust语言教程(6) - 错误处理和可选值 Rust的错误处理 从前面的学习中,我们对于Rust的错误处理应该已...

网友评论

  • 小范屯:在RxJava2 中Observable.just(null),也会抛异常,这个怎么处理
  • 4aff9e170692:为什么IO异常进入了OnError有时候也会造成崩溃。
    东东东鲁:@4aff9e170692 实现了onError方法的话一般是不会崩溃的呀
    4aff9e170692:@东东东鲁 额,就是普通的rxjava+retrofit的操作,flatmap处理状态码非成功的通过Observable.error给onError,简单的判断状态吗或者异常类型,给提示信息。比如网不好时出现的SocketTimeoutException,这个类型给超时提示,但是有时候也崩溃,这个可能和OnErrorNotImplementedException有关吧。断网出现UnknownHostException直接崩愧,这个就。。。最近有点头大,已经被绕进去了
    东东东鲁:@4aff9e170692 有时候?在OnError中会不会又抛出了异常呢
  • 2403dae8b2e4:这只适于对lambda表达式了解的人看
    东东东鲁:@sonuan 可以去了解一下,这个不是重点。

本文标题:RxJava中的错误处理

本文链接:https://www.haomeiwen.com/subject/gkaelttx.html