How do I get Response body when there is an error when using Retrofit 2.0 Observables

21,175

Solution 1

Just check if the throwable is an instance of HttpException and then you can access the retrofit response

if (e instanceof HttpException) {
    ResponseBody body = ((HttpException) e).response().errorBody();
    ...
}

Then you can use the converter to deserialize it (or do it yourself).

Solution 2

You can add this code block to display the error message.

@Override
public void onFailure(Throwable t) {

 if (t instanceof HttpException) {
        ResponseBody body = ((HttpException) t).response().errorBody();
        Gson gson = new Gson();
        TypeAdapter<ErrorParser> adapter = gson.getAdapter
                (ErrorParser
                        .class);
        try {
            ErrorParser errorParser =
                    adapter.fromJson(body.string());

            Logger.i(TAG, "Error:" + errorParser.getError());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Solution 3

Retrofit returns the Throwable Object which is a type of HttpException. First Step that you need to do is that you should know the structure of you error body object. Will show how to do it Kotlin. Once you know the structure, you need to create Error.kt file like shown below :

package com.test.test.qr.data.network.responsemodel
import com.google.gson.annotations.SerializedName

data class Error(
    @SerializedName("code")
    val code: String,
    @SerializedName("message")
    val message: String
)

Now you need to parse the body from HttpException to Error.Kt you created. This can be done as shown below :

if(it is HttpException) {
    val body = it.response()?.errorBody()
    val gson = Gson()
    val adapter: TypeAdapter<Error> = gson.getAdapter(Error::class.java)
    try {
        val error: Error = adapter.fromJson(body?.string())
        Log.d("test", " code = " + error.code + " message = " + error.message)
    } catch (e: IOException) {
       Log.d("test", " Error in parsing")
    }
}

Where it is the Throwable you get in onError() from retrofit. Hope it helps. Happy Coding...:-)

Share:
21,175
achie
Author by

achie

Java/Android developer. Android enthusiast. I do poke around other programming languages as well from time to time.

Updated on September 15, 2020

Comments

  • achie
    achie over 3 years

    I am using Retrofit 2.0 to make api calls that return Observables. It all works good when the call went through fine and the response is as expected. Now let's say we have an error response, it throws an onError. I would like to read the response body even when it is an Error.

    Example

    @FormUrlEncoded
    @POST("tokenLogin")
    Observable<LoginResponse> loginWithToken(
            @Field("token") String pin
    );
    

    When the request and response are valid, I get the right observable and onError is being called as expected when there is an error.

    Correct Response:

    { "status" : "authenticated" }
    

    The Observable converts this into the right Observable and I can read the response as LoginResponse object.

    Now, the Error Response is as follows:

    { "errorMessage" : "You need to take some xyz action" }
    

    I would like to read that error response and display the message to the user. How do I go about doing that?

  • Alston
    Alston over 4 years
    I'd like to know about your ErrorParser. Thanks :)
  • Akhila Madari
    Akhila Madari over 4 years
    @Alston ErrorParser is the JSON class
  • Bipin Bharti
    Bipin Bharti almost 3 years
    @Akshay Shinde Thank you bro it's helped me. Awsome Work
  • Makari Kevin
    Makari Kevin over 2 years
    Working like a charm!!