Skip to content Skip to sidebar Skip to footer

How To Handle Error In Retrofit 2.0

I want to handle error in Retrofit 2.0 Got e.g. code=404 and body=null, but errorBody() contains data in ErrorModel (Boolean status and String info). This is errorBody().content: [

Solution 1:

If you want to get data when error response comes (typically a response code except 200) you can do it like that in your onResponse() method:

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

When generating YourErrorPojo.class do following steps :

  1. Go to Json Schema 2 Pojo

  2. Paste your example Json, and select source type Json , annotation Gson

  3. Your example Json is : {"status":false,"info":"Provided email doesn't exist."}

  4. Click Preview and it will generate your Pojo class for you.

Add this to your build.gradle : compile 'com.google.code.gson:gson:2.7'

I used Gson in this solution but you can get your Json string using: response.errorBody().string()

Solution 2:

Retrofit doesn't see 404 as a failure, so it will enter the onSuccess.

response.isSuccessful() is true if the response code is in the range of 200-300, so it will enter the else there.

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

However since your response was not successful, you do not get the response body with .body(), but with errorBody(), errorBody will filled when the request was a success, but response.isSuccessful() returns false (so in case of a status code that is not 200-300).

Solution 3:

I'm using this library Retrobomb, you don't have to serialize at that level. it's easy to use and customize. It supports annotation for each error type or error code. If you prefer you can unwrap all errors and handle by your self.

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

Solution 4:

If you want to get data when error response comes (typically a response code except 200) you can do it like that in your onResponse() method:

overridefunonResponse(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...
            }
        } elseif (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..
            }
        }
    }
}

Solution 5:

For Kotlin:

Just follow this code to convert your errorBody to your response:

if(response.isSuccessful){
     valdata = response.body()!!
               
 }else {
    val gson = GsonBuilder().create()

    try {
        var pojo = gson.fromJson(
            response.errorBody()!!.string(),
            CommentResponse::class.java)
            Log.e("ERROR_CHECK","here else is the error$pojo")

     } catch (e: IOException) {
           // handle failure at error parse
  }
}

Post a Comment for "How To Handle Error In Retrofit 2.0"