Как справиться с ошибкой в ​​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...");
        }
    });
 Raghunandan11 июл. 2016 г., 12:13
можешь поставить код
 y07k211 июл. 2016 г., 12:18
Этот код вы имеете в виду?

Ответы на вопрос(4)

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

@ErrorMapping(code = 401, errorType = Unauthorized.class)
@PATCH("/v1/widgets/{id}")
  Single<Widget> updateWidget(@Path("id") String id, @Body Widget widget);
Решение Вопроса

когда приходит ответ об ошибке (обычно код ответа, кроме 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 выполните следующие шаги:

Идти кJson Schema 2 Pojo

Вставьте свой примерJsonи выберите тип источникаJson , аннотацияGson

Ваш примерJson является :{"status":false,"info":"Provided email doesn't exist."}

Нажмитепредварительный просмотр и это сгенерирует вашPojo класс для вас.

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

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

 y07k211 июл. 2016 г., 14:15
Я попробовал этот код:Gson gson = new GsonBuilder().create(); StatusInfoModel error = new StatusInfoModel(); try { error = gson.fromJson(response.errorBody().string(), StatusInfoModel.class); showToast(getApplicationContext(), error.getInfo()); } catch (IOException e) { // handle failure to read error }, но есть ошибка:Class must either be declared abstract or implement abstract method.
 y07k211 июл. 2016 г., 14:22
s32.postimg.org/eww0vfotx/error.png, Когда я удаляюelse Ошибка оператора исчезает.
 Yasin Kaçmaz11 июл. 2016 г., 14:19
@ y07k2 Можете ли вы предоставить скриншот, и я его посмотрю?
 Yasin Kaçmaz11 июл. 2016 г., 14:30
@ y07k2 Ах, я вижу твою ошибку, потому что я пропустил одну "}", я добавил ее в свой ответ. Пожалуйста, посмотрите отредактированный ответ.
 y07k211 июл. 2016 г., 14:49
Работает отлично! Спасибо! :) П.С. Любая идея, как я могу упростить это (я имею в виду положить в метод и вызвать его в разных местах)?
 Yasin Kaçmaz11 июл. 2016 г., 14:55
@ y07k2 если вы уверены, что получили тот же ответ, когда произошло 404, вы можете упростить его. В моем API, когда я получаю ответ, кроме 200, я получаю такой же ответ, как:{ "code" : 401, "message": "Authorization has been denied" }

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

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).

 y07k211 июл. 2016 г., 14:24
Это странно. Почему я получаю эти данные вerrorBody(), не вbody()?
 y07k211 июл. 2016 г., 14:19
Да, я знаю, что это можно сделать так, но я не хочу печататьString errorMsg каждый раз, когда я могу (по крайней мере, я верю, что могу) получить, если отerrorBody().
 Tim Castelijns11 июл. 2016 г., 14:23
errorBody для, когда возникает ошибка, которая не применяется в случае 404. 404 рассматривается как успех
 gonczor05 мар. 2017 г., 23:30
«response.isSuccessful () имеет значение true, если код ответа находится в диапазоне 200-300». Если быть точным: ответы http, начинающиеся с 2XX, это успехи, перенаправления 3XX, ошибки на стороне клиента 4XX и ошибки на стороне сервера 5XX.
 Tim Castelijns11 июл. 2016 г., 14:27
Виноват.errorBody содержит ответ, если ответ не был успешным. Так что в случае, если не было ошибки, но код состояния не был 200-300. Код состояния 404 будет иметь ответ в errorBody, как вы сказали

когда приходит ответ об ошибке (обычно это код ответа, кроме 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..
                        }
                }
            }
        }

Ваш ответ на вопрос