13

I've implemented okhttp in my android client for network calls.

When i get a failure response i get the failure code and the text related to the code as a message but i don't get the custom failure response that the server sends me. In my failure response in the implemented code the message i get is just "Bad Request".

Whereas the same response from the browser is as follows. enter image description here

How do i get the error message the server is giving me back?

My code

private void executeCall(Request request, final ResponseListener listener) {
        mOKHttpClient.newCall(request)
                     .enqueue(new Callback() {
                         @Override
                         public void onFailure(Call call, IOException e) {                              
                             postFailure(listener, (String) call.request()
                                                                .tag(),e.toString());
                         }

                         @Override
                         public void onResponse(Call call, final Response response) throws IOException {
                             if(response.isSuccessful()) {
                                 String responseString = response.body().string();                                   
                                 postSuccess(listener, (String)call.request().tag(), responseString);
                             }
                             else {                                 
                                 postFailure(listener, (String)call.request().tag(),response.code()+","+response.message());
                             }
                         }
                     });
    }

Here's my response in case of failure. enter image description here

usr30911
  • 2,731
  • 7
  • 26
  • 56
  • It may be possible when your request is fail server sends failure code 400 and therefore it is showing you bad request, so for failure response also you need to set status 200 and message then only it will accept response from server – Vickyexpert Aug 30 '16 at 04:34

2 Answers2

22

You will have to catch error response by body() because response.message() returns HTTP status message.

In the screen shot provided by you:

Status is broken down in OkHttp like response.code() for HTTP status code which is 400 in your case and response.message() for HTTP status message which is Bad Request in your case.

The body of the response (be it success or failure) is response.body(). And if you want to get it as a String, then call response.body().string().

@Override
public void onResponse(Call call, final Response response) throws IOException {
     if(response.isSuccessful()) {
         String responseString = response.body().string();                                   
         postSuccess(listener, (String)call.request().tag(), responseString);
     }
     else {               
        String errorBodyString = response.body().string();                  
        postFailure(listener, (String)call.request().tag(),response.code()+","+errorBodyString);
     }
}

As per comments:

Since you want to read Message object from the response, try to do like this:

JSONObject object = new JSONObject (response.body().string());
String messageString = object.getString("Message");
Mehul Kabaria
  • 6,404
  • 4
  • 25
  • 50
Rohit Arya
  • 6,751
  • 1
  • 26
  • 40
  • 2
    response.body.string() returns something like this okhttp3.internal.http.RealResponseBody@528ae030 – usr30911 Aug 30 '16 at 04:36
  • no, `response.body` will not give you that. And it clearly looks its memory reference. Inspect again and try calling `response.body().string()`. – Rohit Arya Aug 30 '16 at 04:38
  • i did returns the same,i figured out why. I had to access it as a json object, see updated code http://pastebin.com/Lp7eBnb2 also this SO post helped me figure it out http://stackoverflow.com/a/36857049/3518278 updated your answer il accept it. – usr30911 Aug 30 '16 at 04:48
  • Okay, so you want to read `Message` Object of the body? Well, in that case, Yes you will have to convert the String response into JSON object to read. You correctly pointed it. – Rohit Arya Aug 30 '16 at 04:55
  • @ViVekH, check the updated code, that should work. :) – Rohit Arya Aug 30 '16 at 05:00
2

if you are trying to get (okhttp3.ResponseBody) errorResponse from Retrofit response do this..

                // Retrofit onResponseCall
                @Override
                public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {

                    if (response.errorBody() != null) {

                        try {
                            Log.e("errorResponse","" + response.errorBody().toString());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                     }
                }
                   
Adarsh Vijayan P
  • 2,964
  • 2
  • 16
  • 27
  • Where should I do this? Please elaborate on your answer. – xeruf Mar 21 '19 at 11:11
  • If you are using Retrofit call for api response, then this Overrided method **onResponse** is a part of `responseCall.enqueue(Call call , Response response)` – Adarsh Vijayan P Mar 21 '19 at 11:27
  • I use Retrofit with RxJava, I apparently don't get a "Call" object there :/ – xeruf Mar 22 '19 at 08:39
  • Check this out: [Retrofit— A simple Android tutorial](https://medium.com/@prakash_pun/retrofit-a-simple-android-tutorial-48437e4e5a23) – Adarsh Vijayan P Mar 22 '19 at 10:42
  • I have used robospice with okhttp. Now I have migrated okhttp to okhttp3. Shall I use the okhttp3 for the RequestListener and spiceException. – sejn Sep 19 '20 at 07:16
  • There is no `string` member function, only `toString`. – rwst Mar 17 '22 at 17:26