io.reactivex.exceptions.UndeliverableException:java.io.InterruptedIOException

Posted

技术标签:

【中文标题】io.reactivex.exceptions.UndeliverableException:java.io.InterruptedIOException【英文标题】:io.reactivex.exceptions.UndeliverableException: java.io.InterruptedIOException 【发布时间】:2019-01-30 11:41:46 【问题描述】:

我使用RxJavaRetrofit发出网络请求,但偶尔会收到错误反馈。 ApiManager.java:216是我常用参数的add方法。

错误信息:

io.reactivex.exceptions.UndeliverableException: java.io.InterruptedIOException
    at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349)
    at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onError(ObservableUnsubscribeOn.java:67)
    at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onError(BodyObservable.java:72)
    at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:55)
    at io.reactivex.Observable.subscribe(Observable.java:10955)
    at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
    at io.reactivex.Observable.subscribe(Observable.java:10955)
    at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn.subscribeActual(ObservableUnsubscribeOn.java:32)
    at io.reactivex.Observable.subscribe(Observable.java:10955)
    at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
    at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452)
    at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61)
    at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:760)
Caused by: java.io.InterruptedIOException
    at okhttp3.internal.http2.Http2Stream.waitForIo(Http2Stream.java:579)
    at okhttp3.internal.http2.Http2Stream.takeResponseHeaders(Http2Stream.java:143)
    at okhttp3.internal.http2.Http2Codec.readResponseHeaders(Http2Codec.java:120)
    at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:75)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at com.fc.happygo.net.ApiManager$SignInterceptor.intercept(ApiManager.java:216)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
    at okhttp3.RealCall.execute(RealCall.java:69)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
    at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
    ... 14 more

ApiManager.java:216:

public static class SignInterceptor implements Interceptor 

        @Override
        public Response intercept(Chain chain) throws IOException 
            Request request = chain.request();
          //...add sign parameter
            return chain.proceed(request);//line: 216
        
    

OkHttpClient:

OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .addInterceptor(new SignInterceptor());

以上是相关代码。错误消息只是偶尔出现。在测试期间从未发生过。我该如何解决这个问题?

【问题讨论】:

推荐阅读:github.com/ReactiveX/RxJava/blob/2.x/docs/… 【参考方案1】:

正如建议的那样,发生错误是因为没有注册Subscriber 将错误传递到并且没有通过RxJavaPlugins.setErrorHandler() 设置的全局设置

然而,问题的症结似乎是因为

okhttp3.internal.http2.Http2Stream.waitForIo(Http2Stream.java:579)
当进行 API 调用的 Rx 流被处理掉时,它正在等待并被中断。

从堆栈跟踪看来,您遇到了这样的情况:

  /**
   * Removes and returns the stream's received response headers, blocking if necessary until headers
   * have been received. If the returned list contains multiple blocks of headers the blocks will be
   * delimited by 'null'.
   */
  public synchronized List<Header> takeResponseHeaders() throws IOException 
所以你需要做的是确保当你取消订阅你的 Rx 流进行这个 API 调用时,你首先取消与流的连接(我只是在这里猜测,它是打开的或包含多个标题块)。这应该照顾持续的等待并解决崩溃。

但是,简单地为全局处理程序添加插件将是一种快速修复,因为它会停止崩溃并让您恢复。

【讨论】:

以上是关于io.reactivex.exceptions.UndeliverableException:java.io.InterruptedIOException的主要内容,如果未能解决你的问题,请参考以下文章