Retrofit 2.0にアップグレードして、RxJavaをAndroidプロジェクトに追加しようとしています。 API呼び出しを行っており、サーバーからエラー応答があった場合にエラーコードを取得したい。
Observable<MyResponseObject> apiCall(@Body body);
そして、RxJava呼び出しで:
myRetrofitObject.apiCall(body).subscribe(new Subscriber<MyResponseObject>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MyResponseObject myResponseObject) {
//On response from server
}
});
Retrofit 1.9では、RetrofitErrorがまだ存在していたため、次の操作を行うことでステータスを取得できました。
error.getResponse().getStatus()
RxJavaを使用してRetrofit 2.0でこれをどのように行いますか?
あなたがしたようにAPI呼び出しを宣言する代わりに:
Observable<MyResponseObject> apiCall(@Body body);
次のように宣言することもできます。
Observable<Response<MyResponseObject>> apiCall(@Body body);
その後、次のようなサブスクライバーが作成されます。
new Subscriber<Response<StartupResponse>>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {
Timber.e(e, "onError: %", e.toString());
// network errors, e. g. UnknownHostException, will end up here
}
@Override
public void onNext(Response<StartupResponse> startupResponseResponse) {
Timber.d("onNext: %s", startupResponseResponse.code());
// HTTP errors, e. g. 404, will end up here!
}
}
したがって、エラーコードを含むサーバーの応答もonNext
に配信され、reponse.code()
を呼び出すことでコードを取得できます。
http://square.github.io/retrofit/2.x/retrofit/retrofit/Response.html
EDIT:OK、私はついに、e-nouriが彼らのコメントで言ったこと、すなわち2xxコードだけがonNext
に対してすることを調べることに回りました。私たちはどちらも正しいことがわかりました:
呼び出しが次のように宣言されている場合:
Observable<Response<MyResponseObject>> apiCall(@Body body);
またはこれでさえ
Observable<Response<ResponseBody>> apiCall(@Body body);
all応答は、エラーコードに関係なくonNext
になります。これは、すべてがRetrofitによってResponse
オブジェクトにラップされているため可能です。
一方、呼び出しが次のように宣言されている場合:
Observable<MyResponseObject> apiCall(@Body body);
またはこれ
Observable<ResponseBody> apiCall(@Body body);
実際、2xx応答のみがonNext
に送られます。それ以外はすべてHttpException
でラップされ、onError
に送信されます。また、Response
ラッパーがなければ、onNext
に何を発行すべきなのかリクエストが成功しなかったことを考えると、送出する唯一の賢明なものはnull
...です。
これに置かれたonErrorメソッド内でコードを取得
((HttpException) e).code()
Retrofit2のコードを持つすべての応答2xxがonNext()コールバックから呼び出され、残りのHTTPコードが4xxのように、 5xxはonError()コールバックで呼び出されますKotlinを使用してonError()でこのようなものを思いつきました:
mViewReference?.get()?.onMediaFetchFinished(downloadArg)
if (it is HttpException) {
val errorCode = it.code()
mViewReference?.get()?.onMediaFetchFailed(downloadArg,when(errorCode){
HttpURLConnection.HTTP_NOT_FOUND -> R.string.check_is_private
else -> ErrorHandler.parseError(it)
})
} else {
mViewReference?.get()?.onMediaFetchFailed(downloadArg, ErrorHandler.parseError(it))
}