Je veux gérer une erreur dans Retrofit 2.0
Obtenu par exemple code=404
et body=null
, mais errorBody()
contient des données dans ErrorModel
(Boolean status
et String info
).
Ceci est errorBody().content
: [text=\n{"status":false,"info":"Provided email doesn't exist."}]
.
Comment puis-je obtenir ces données?
Merci de m'aider!
Voici mon code pour la demande de modification:
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...");
}
});
Si vous voulez obtenir des données quand une réponse d'erreur survient ( généralement un code de réponse sauf 200 ), vous pouvez le faire comme cela dans votre méthode 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) { }
}
Lors de la génération de YourErrorPojo.class
, procédez comme suit:
Allez à Json Schema 2 Pojo
Collez votre exemple Json
et sélectionnez le type de source Json , annotation Gson
Votre exemple Json
est: {"status":false,"info":"Provided email doesn't exist."}
Pojo
pour vous.Ajoutez ceci à votre build.gradle
: compile 'com.google.code.gson:gson:2.7'
J'ai utilisé Gson
dans cette solution, mais vous pouvez obtenir votre Json
comme: response.errorBody().string()
et le manipuler, faites tout ce que vous voulez.
Le rattrapage ne considère pas le 404 comme un échec, il entrera donc dans onSuccess.
response.isSuccessful()
est vrai si le code de réponse est compris entre 200 et 300, il entrera donc le reste ici.
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));
}
Cependant, puisque votre réponse a échoué, vous n'obtenez pas le corps de la réponse avec .body()
, mais avec errorBody()
, errorBody sera rempli lorsque la demande aboutira, mais response.isSuccessful()
renvoie false (donc dans le cas d'un code d'état autre que 200-300). ).
J'utilise cette bibliothèque Retrobomb , vous n'avez pas à sérialiser à ce niveau. Il est facile à utiliser et à personnaliser. Il supporte les annotations pour chaque type d'erreur ou code d'erreur. Si vous préférez, vous pouvez supprimer toutes les erreurs et les gérer vous-même.
@ErrorMapping(code = 401, errorType = Unauthorized.class)
@PATCH("/v1/widgets/{id}")
Single<Widget> updateWidget(@Path("id") String id, @Body Widget widget);
Si vous voulez obtenir des données quand une réponse d'erreur arrive (généralement un code de réponse sauf 200), vous pouvez le faire comme ça dans votre méthode 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..
}
}
}
}