16

I am struggling with retrofit. When I post a request in my browser i get such a request: enter image description here

And that's what I expect. However, when I try to parse this in my app I kept getting responses as in this thread. I've found tried to implement this solution, but my errorBody does not even resemble the answer from my browser: enter image description here How can I get this JSON?

Just in case this is my response handler code:

void handleResponse(Response response){
    TextView textView = (TextView)findViewById(R.id.empty_list_tv);
    if(response.isSuccessful())
        textView.setText(response.toString());
    else {
        Gson gson = new Gson();
        ErrorResponse errorResponse = gson.fromJson(
                response.errorBody().toString(),
                ErrorResponse.class);
        textView.setText(response.errorBody().toString());
    }
}

And my ErrorResponse:

public class ErrorResponse {
    @SerializedName("message")
    private String message;
    @SerializedName("error")
    private Error error;

    public String getMessage() {
        return message;
    }

    public Error getError() {
        return error;
    }
}
Community
  • 1
  • 1
gonczor
  • 3,994
  • 1
  • 21
  • 46
  • Is `response.errorBody().toString(),` a JSON? – Coder Mar 06 '17 at 16:04
  • No. At least I don't recognize it is: "okhttp3.ResponseBody$1@f0473b9" – gonczor Mar 06 '17 at 16:09
  • You are trying to construct `errorResponse` from GSON's fromJson which expects a JSON. Do you see where you are doing wrong? – Coder Mar 06 '17 at 16:11
  • 2
    Ah. That's what you mean. I see I've used `toString()` instead of `string()`. When I evaluate `response.errorBody().string()` I get `{"error":{"message":"Not Found","error":{"status":404}}}` which is what I want. I'll post your answer to mark problem as solved. Thanks :) – gonczor Mar 06 '17 at 16:17
  • Glad I could help!! – Coder Mar 06 '17 at 16:23

3 Answers3

39

You are using toString() in GSON's fromJson which is not a JSON content. Replace your toString() as string() which will give you the JSON body. Also make sure to use the string() method only once and save the response in a variable, because it will return empty string if you used it again.

Khalid Taha
  • 3,183
  • 5
  • 27
  • 43
Coder
  • 2,153
  • 1
  • 16
  • 21
  • 1
    this worked, but if I called the `string()` method second time it will return empty string – Khalid Taha Dec 20 '17 at 10:36
  • 1
    @KhalidTaha What do you exactly mean when you say you are calling the method second time? Can you elaborate a bit – Coder Jan 08 '18 at 20:50
  • I mean if you call `string()` method for the first time it will return the correct string, but if you called it another once, it will return empty string. – Khalid Taha Jan 09 '18 at 13:59
  • 2
    Care to elaborate or update my answer with valid explanation for that? It might help someone else looking for the answer @KhalidTaha – Coder Jan 09 '18 at 17:50
  • Thanks for the answer. using ```string()``` works but I had to surround it in a try catch. – Denny Nov 12 '20 at 00:12
  • If you need to use response.errorBody().string() more than once, check this answer out: https://stackoverflow.com/a/73857446/9952567 – Vladimir Kattsyn Sep 26 '22 at 17:42
9

you use string(), not toString()

 ErrorResponse errorResponse = gson.fromJson(
                response.errorBody().toString(),
                ErrorResponse.class);

to

ErrorResponse errorResponse = gson.fromJson(
                response.errorBody().string(),
                ErrorResponse.class);
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78
0

In Kotlin

Parse the error body

val errorResponse = Gson().fromJson(response.errorBody()?.charStream(),ErrorResponse::class.java)
Eldhopj
  • 2,703
  • 3
  • 20
  • 39