Как справиться с ошибкой в Retrofit 2.0

Я хочу обработать ошибку в Retrofit 2.0

есть например code=404 и body=null, а errorBody() содержит сведения в ErrorModel (Boolean status и String info).

это errorBody().content: [text=n{"status":false,"info":"Provided email doesn't exist."}].

как я могу получить эти данные?

Спасибо за помощь!

это мой код для запроса Ретрофит:

ResetPasswordApi.Factory.getInstance().resetPassword(loginEditText.getText().toString())
    .enqueue(new Callback<StatusInfoModel>() {
        @Override
        public void onResponse(Call<StatusInfoModel> call, Response<StatusInfoModel> response) {
            if (response.isSuccessful()) {
                showToast(getApplicationContext(), getString(R.string.new_password_sent));
            } else {
                showToast(getApplicationContext(), getString(R.string.email_not_exist));
            }
        }

        @Override
        public void onFailure(Call<StatusInfoModel> call, Throwable t) {
            showToast(getApplicationContext(), "Something went wrong...");
        }
    });

4 ответов


если вы хотите получить информацию когда приходит ответ об ошибке (обычно код ответа, кроме 200) вы можете сделать это в ваш onResponse() способ:

if (response.code() == 404) {
    Gson gson = new GsonBuilder().create();
    YourErrorPojo pojo = new YourErrorPojo();
    try {
         pojo = gson.fromJson(response.errorBody().string(), YourErrorPojo.class);
         Toast.makeText(getApplicationContext(), pojo.getInfo(), Toast.LENGTH_LONG).show();
    } catch (IOException e) { }
}

при создании YourErrorPojo.class выполните следующие действия:

  1. на JSON Schema 2 Pojo

  2. вставьте свой пример Json и выберите тип источника в JSON аннотации Gson

  3. ваш пример Json - это : {"status":false,"info":"Provided email doesn't exist."}

  4. клик предварительный просмотр и он будет генерировать код Pojo класс для вас.

добавьте это в ваш build.gradle : compile 'com.google.code.gson:gson:2.7'

я Gson в этом решении, но вы можете сделать свой Json как : response.errorBody().string() и справиться с этим, делать sth все, что вы хотите.


Retrofit не видит 404 как сбой, поэтому он войдет в onSuccess.

response.isSuccessful() истинно, если код ответа находится в диапазоне 200-300, поэтому он будет вводить там else.

if (response.isSuccessful()) {
    showToast(getApplicationContext(), getString(R.string.new_password_sent));
} else {
    // A 404 will go here

    showToast(getApplicationContext(), getString(R.string.email_not_exist));
}

однако, поскольку ваш ответ не был успешным, вы не получаете тело ответа с .body(), но с errorBody(), errorBody будет заполнен, когда запрос был успешным, но response.isSuccessful() возвращает false (так что в случае кода состояния, который не 200-300).


Если вы хотите получить данные, когда приходит ответ на ошибку (обычно код ответа, кроме 200), вы можете сделать это так, как в методе onResponse ():

  override fun onResponse(call: Call<LoginData>?, response: Response<LoginData>?) {
            if (response != null) {
                if (response.code() == 200 && response.body() != null) {
                    val loginData = response.body()
                    if (loginData != null) {
                     //Handle success case...
                    }
                } else if (response.code() == 401) {
                    val converter = ApiClient.getClient()?.responseBodyConverter<ErrorResponseData>(
                            ErrorResponseData::class.java, arrayOfNulls<Annotation>(0))
                    var errorResponse: ErrorResponseData? = null
                        errorResponse = converter?.convert(response.errorBody())
                        if (errorResponse != null) {
                            //Handle Error case..
                        }
                }
            }
        }

Я использую эту библиотеку Retrobomb, вам не нужно сериализоваться на этом уровне. легко использовать и подгонять. Он поддерживает аннотацию для каждого типа ошибки или кода ошибки. Если вы предпочитаете, вы можете развернуть все ошибки и справиться самостоятельно.

@ErrorMapping(code = 401, errorType = Unauthorized.class)
@PATCH("/v1/widgets/{id}")
  Single<Widget> updateWidget(@Path("id") String id, @Body Widget widget);