2017-02-20 32 views
3

我有一个RxJava链请求应该释放一些锁的onError(),或的onComplete(),所以,基本上,我的问题是什么:当我设置读取超时连接,并写信给我OkHttpClient,我没有得到所需的行为。我使用Retrofit2和OkHttp3.6.0这里是我的简化客户端:HTTP失败:java.net.SocketException:套接字关闭;不会引发异常处理方法

OkHttpClient.Builder builder = new OkHttpClient.Builder() 
      .readTimeout(30, TimeUnit.SECONDS) 
      .connectTimeout(30, TimeUnit.SECONDS) 
      .writeTimeout(30, TimeUnit.SECONDS) 
OkHttpClient okHttpClient = builder.build(); 

这里的链请求我有一个简化版本:

public <T extends Response> Observable<T> doSomething(Observable<T> base) { 
    isLocked = true; 
    return someApiCall() 
       .flatMap(apiResponse -> handleResponse(apiResponse, base) 
        .doOnError(throwable -> { 
         isLocked = false; 
        }) 
        .doOnCompleted(() -> { 
         isLocked = false; 
        })); 
} 

handleResponse()使得另一个API调用和返回Observable<Response<Something>>但是,正如我所说的,它有时会失败,并且它不会完成Observable,所以,onError()或onComplete()永远不会被调用。我也尝试了onTerminate(),但没有运气。当我从OkHttlClient删除超时设置时,SocketException实际上被抛出并被捕获,释放了isLocked变量。我试过用try {} catch (Exception e) {}块封装handleResponse() return语句,但即使在设置了自定义超时时也不能捕获SocketException。有任何想法吗?

+0

做handleResponse做Retrofit调用吗?你怎么定义“完成可观察”?任何问题怎么可能是因为它似乎是你申请的doOnError /竣工刚上称为内flatMapped,于是 - someApiCall()可能会失败,你会不会抓住它 – yosriz

+0

是它确实做了改造通话。正如我提到这是一个简单的链条中,真正应该是originalApiCall(失败) - > apiCallOne - > apiCallTwo - > originalApiCall(这是一个会话更新链)我试着将两个doOnError()和doOnTerminate到外打电话,但没有运气。问题是除了Socket关闭的 –

+0

好了,我明白了,所有其他异常都会在链中被捕获,那么SocketException会发生什么?你怎么知道这是exepction? – yosriz

回答

0

事实证明,要求是越来越退订,这引起了HTTP FAILED: java.net.SocketException: Socket closed错误的出现,所以,将溶液刚刚添加该代码链:

.doOnUnsubscribe(() -> { 
    isLocked = false; 
}) 

我还是不明白为什么自定义超时值触发SocketException,但我想的是,套接字等待超时到期,关闭或完成请求和关闭,但它得到了由unsubscribe调用中断,因此意外关闭。

0

在改进2中,HTTP层以下/以外的例外不会被报告为Response<?>,而是通过onError作为实际例外。

对您而言,您应该将doOnError/doOnCompleted移出flatMap;因为它现在只对handleResponse中产生的错误作出响应 - 但如果someApiCall返回错误Observable,则不会调用该方法。

+0

我知道并且我尝试在外部调用中添加doOnError和doOnCompleted,但是没有运气,甚至doOnTerminate和doAfterTerminate,它们从未到达(在Socket异常的情况下)。真正的问题是,所有其他异常都被链接捕获,除了Socket关闭,似乎在其他地方处理... –

+0

你可以用“推迟”来包装呼叫吗?像'Observable.defer(() - > someApiCall())' –

+0

因为我对RxJava相当陌生,请告诉我这样做有什么好处?我会试试看,但我不知道会发生什么。 –

0

我解决了这个情况在Android中使用与建筑商设置的选项retryOnConnectionFailure(真)。

鉴于改造2只收到OkHttpClient对象。

相关问题