Получить код состояния ответа с помощью Retrofit 2.0 и RxJava

Я пытаюсь обновить до 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()

как вы это делаете с Retrofit 2.0 с помощью RxJava?

3 ответов


вместо объявления вызова 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: хорошо, я, наконец, добрался до того, что e-nouri сказал в своем комментарии, а именно, что только 2xx коды будут onNext. Оказывается, мы оба правы:--19-->

если вызов объявлен следующим образом:

Observable<Response<MyResponseObject>> apiCall(@Body body);

или даже этот

Observable<Response<ResponseBody>> apiCall(@Body body);

все ответы в конечном итоге в onNext, независимо от их кода ошибки. Это возможно, потому что все обернуто в 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 () обратный вызов, используя Котлин Я придумал что-то подобное в 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))
  }