2017-02-20 11 views
3

いくつかのロックonError()、またはonComplete()を解放する必要があるRxJavaチェーン要求がありますので、基本的に私の問題は何ですか:私が読み込みを設定し、 OkHttpClient、私は希望の動作を取得しません。 、HTTPが失敗しました:java.net.SocketException:Socket closed;例外処理メソッドを起動しません

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>>を返しますが:ここで私が持っているチェーン要求の簡易版だ

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

:私はここに私の単純化クライアントだRetrofit2とOkHttp3.6.0を使用しています私が言ったように、それは時々HTTP FAILED: java.net.SocketException: Socket closedで失敗し、Observableを終了しないので、onError()またはonComplete()は決して呼び出されません。私はonTerminate()も試みましたが、運がありません。 OkHttlClientからタイムアウト設定を削除すると、SocketExceptionが実際にスローされて捕捉され、isLocked変数を解放します。私はhandleResponse()の返信文をtry {} catch (Exception e) {}ブロックでラップしようとしましたが、カスタムタイムアウトが設定されている場合でもSocketExceptionをキャッチしません。何か案は?

+0

handleResponseもまたRetrofitコールを行いますか?あなたは「観察可能なものを完成させる」と何を定義しますか? doOnErrorを適用しているように見えるかもしれません/内部のflatMappedで完了しました。someApiCall()は失敗し、キャッチしません。 – yosriz

+0

はい、Retrofit呼び出しを行います。私はこれを単純化したチェーンだと言いますが、実際のものはoriginalApiCall(失敗) - > apiCallOne - > apiCallTwo - > originalApiCall(セッション更新チェーン)です。doOnError()とdoOnTerminateの両方を外部呼び出しに追加しようとしました。運がない。問題は、SocketExceptionを除いて、他のすべての例外がチェーン内でキャッチされていることです。 –

+0

okです。だから、SocketExceptionはどうなりますか?それがどういうふうに分かったのですか? – yosriz

答えて

0

それは要求がHTTP FAILED: java.net.SocketException: Socket closedエラーの出現を引き起こした、解除になったので、解決策は、単にチェーンにこのコードを追加したことが判明しますカスタムタイムアウト値はSocketExceptionをトリガーしていましたが、タイムアウトがタイムアウトして終了するか、要求を完了して閉じるまでソケットが待機していたとしますが、unsubscribeコールによって割り込みが発生し、予期せず終了しました。

0

Retrofit 2では、HTTPレイヤーの下/上の例外はResponse<?>として報告されていませんが、実際の例外としてはonErrorと報告されています。あなたのケースでは

、あなたはflatMapのうちdoOnError/doOnCompletedを移動する必要があります。今のところhandleResponseで生成されたエラーに応答しますが、someApiCallがObservableエラーを返した場合、そのメソッドは呼び出されません。私はまだ理由を理解していない

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

+0

私は認識していますそれとdoOnErrorとdoOnCompletedを外側の呼び出しに追加しようとしましたが、(ソケット例外の場合には)決して到達しないdoOnTerminateとdoAfterTerminateさえも運がありません。本当の問題は、他のすべての例外がチェーンによって捕らえられていることです。ソケットのクローズは、他のどこかで処理されているようです... –

+0

コールを 'defer'でラップできますか? 'Observable.defer(() - > someApiCall())'のように –

+0

私はRxJavaをかなり新しくしています。私はそれを試してみるだろうが、私は何を期待するか分からない。 –

0

私は、この状況をビルダーで設定されたretryOnConnectionFailure(true)オプションを使ってAndroidで解決しました。

Retrofit 2がOkHttpClientオブジェクトを受け取ったばかりであることを考えると、

関連する問題