【问题标题】:Handle Network error with Retrofit observable使用 Retrofit observable 处理网络错误
【发布时间】:2014-10-02 11:56:39
【问题描述】:

当使用带有 Retrofit 的 Observables 时,你如何处理网络故障?

鉴于此代码:

Observable<GetJobResponse> observable = api.getApiService().getMyData();
observable
    .doOnNext(new Action1<GetJobResponse>() {
        @Override
        public void call(GetJobResponse getJobResponse) {
            //do stuff with my data
        }
    })
    .doOnError(new Action1<Throwable>() {
        @Override
        public void call(Throwable throwable) {
            //do stuff with error message
        }
    });

请求在没有网络的情况下失败,并且不会调用 onError。它不会崩溃,而是默默地失败。日志显示 Retrofit 收到错误:

 java.net.UnknownHostException: Unable to resolve host "api-staging.sittercity.com": No address associated with hostname
     at java.net.InetAddress.lookupHostByName(InetAddress.java:424)
     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
     at java.net.InetAddress.getAllByName(InetAddress.java:214)
     at com.squareup.okhttp.internal.Dns$1.getAllByName(Dns.java:29)

使用回调将其简单地传递给 onFailure(RetrofitError 错误)。我怎样才能用 RxJava 实现这一点?

【问题讨论】:

    标签: android observable retrofit rx-java


    【解决方案1】:

    这纯粹是一个 RxJava 问题,与 Retrofit 无关。 doOnError 是一个副作用,因此即使它处理了错误,它也不会“捕获”以防止它向前冒泡。

    您应该查看Error Handling Operators。最基本的选项是onErrorReturn(),它允许您用项目替换错误(GetJobResponse 的实例)。

    您可以在该项目上放置一个“错误”标志,以便以后在订阅observable 时识别它。同样重要的是要知道,如果你不订阅那个 observable,它本质上是“死的”。您应该始终订阅 observables 而不是使用“doOn___”,这只是副作用(应该用于日志记录和其他非关键功能)。

    【讨论】:

    • 感谢您的反馈。我将不得不尝试解决这个问题。
    • @André Staltz 这将我从一个黑暗、深邃的兔子洞中解救了出来,我刚开始沿着 Rx 路径走下去就发现自己身处其中。感谢您的洞察力!
    【解决方案2】:

    我的问题实际上在我的代码中的其他地方。使用 rxJava + Retrofit 处理网络错误非常简单,因为它只是在 onError 方法中抛出一个 RetrofitError:

     @Override
     public void onError(Throwable e) {
         if (e instanceof RetrofitError) {
            if (((RetrofitError) e).isNetworkError()) {
                //handle network error
            } else {
                //handle error message from server
            }
         }
     }
    

    【讨论】:

    • .isNetworkError() 现已折旧。现在使用getKind() == Kind.NETWORK.square.github.io/retrofit/javadoc/retrofit/RetrofitError.html 但除此之外,谢谢!
    • 我应该在哪里覆盖onerror 方法以捕获RetrofitError。当我尝试在subscribe() 方法中执行此操作时,Android Studio 会抛出 Cannot resolve symbol RetrofitError
    • 如果使用 Retrofit 2,它将是 retrofit.HttpException 而不是 RetrofitError
    【解决方案3】:

    请注意,如果您让 observable 发出 onError,所有上游 observable 都将关闭 - 无论您是使用 onErrorReturn 还是 onErrorResumeNext “捕获”它。通常你不希望这样。例如,如果您的流以触发改造请求失败的按钮单击开始,则由于流终止,按钮单击将不再被识别。

    使用Observable&lt;Response&lt;Type&gt;&gt;Observable&lt;Result&lt;Type&gt;&gt; 也可以处理onNext() 中的改造错误。

    s。 http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/

    【讨论】:

      【解决方案4】:

      截至Retrofit2RxJava2 不再有RetrofitError 异常。而它的后继HttpException 只代表HTTP 错误响应码。网络错误应通过IOException处理。

       @Override
       public void onError(Throwable e) {
           if (e instanceof IOException) {
                  //handle network error
           } else if (e instanceof HttpException) {
                  //handle HTTP error response code
           } else {
                  //handle other exceptions
           } 
       }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-29
        • 2017-05-13
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多