ObservablesをRetrofitで使用する場合、ネットワーク障害をどのように処理しますか?
このコードを考えると:
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は呼び出されません。クラッシュはしませんが、静かに失敗します。ログはレトロフィットがエラーを取得していることを示しています:
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でこれを表示するにはどうすればよいですか?
私の問題は実際には私のコードのどこかにありました。 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
}
}
}
これは純粋にRxJavaの問題であり、Retrofitの問題はそれほど多くありません。 doOnError
は副作用であるため、エラーを処理しても、前方にバブリングするのを防ぐという意味では「キャッチ」しません。
エラー処理演算子 を見てください。最も基本的なオプションはonErrorReturn()
で、これを使用してエラーをアイテム(GetJobResponse
のインスタンス)に置き換えることができます。
後でobservable
をサブスクライブするときにそれを識別するために、そのアイテムに「エラー」フラグを付けることができます。また、そのオブザーバブルをサブスクライブしないと、本質的に「デッド」になることを知っておくことが重要です。単なる副作用である「doOn___」を使用するのではなく、常にオブザーバブルをサブスクライブする必要があります(ロギングおよびその他の重要でない機能に使用する必要があります)。
オブザーバブルをonError
で放出させると、onErrorReturn
とonErrorResumeNext
のどちらで「キャッチ」するかに関係なく、上流のすべてのオブザーバブルがシャットダウンします。多くの場合、それは必要ありません。たとえば、ストリームが改造リクエストをトリガーするボタンクリックで始まった場合、ストリームが終了したため、ボタンクリックは認識されなくなります。
_Observable<Response<Type>>
_または_Observable<Result<Type>>
_を使用して、onNext()
の改造エラーも処理します。
s。 http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/
Retrofit2
およびRxJava2
以降、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
}
}