2017-02-20 31 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對象。

相關問題