Как справиться с ошибкой в 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
выполните следующие действия:
вставьте свой пример
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()
и справиться с этим, делать 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);