How to get error message description using Volley
Asked Answered
L

8

18

I'm sending an http request from Android Java using the Volley library to a c# backend. The backend application responds with a error code and description as intended, as well as a StatusDescription. I can see the response status description through wireshark but do not know how to get the description string on the android side.

    final JsonObjectRequest request = new JsonObjectRequest(JsonObjectRequest.Method.POST,
                                url,json,
                            new Response.Listener<JSONObject>() {

                                @Override
                                public void onResponse(JSONObject response) {
                                    TextView mTextView = (TextView) findViewById(R.id.output);
                                    print("Success");
                                }
                            }, new Response.ErrorListener() {

                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    TextView mTextView = (TextView) findViewById(R.id.output);
                                    print("Failure (" + error.networkResponse.statusCode + ")");
//Trying to get the error description/response phrase here
                            }
                        }
                    );

This is the C# code processing the request:

[WebInvoke(Method = "POST", UriTemplate = "users", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] [OperationContract] void addUser(String username, String firstname, String lastname, String email, String hash) { Console.WriteLine(DateTime.Now + " Packet receieved");

        //Stores the response object that will be sent back to the android client
        OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
        String description = "User added";
        response.StatusCode = System.Net.HttpStatusCode.OK;

        //Tries to add the new user
        try
        {
            userTable.Insert(username,firstname,lastname,email,hash);
        }
        catch (SqlException e)
        {
            //Default response is a conflict
            response.StatusCode = System.Net.HttpStatusCode.Conflict;

            description = "Bad Request (" + e.Message + ")";

            //Check what the conflict is
            if (userTable.GetData().AsEnumerable().Any(row => username == row.Field<String>("username")))
            {
                description = "Username in use";
            }
            else if (userTable.GetData().AsEnumerable().Any(row => email == row.Field<String>("email")))
            {
                description = "Email address in use";
            }
            else
            {
                response.StatusCode = System.Net.HttpStatusCode.BadRequest;
            }
        }

        //display and respond with the description
        Console.WriteLine(description);
        response.StatusDescription = description;
    }

I've looked through other peoples questions but can't seem to find the answer I'm looking for. Anyone know how to do this? Many methods I have tried resulted in empty curly braces, indicating JSON with an empty body. I am trying specifically to get the status description.

Lippi answered 7/3, 2016 at 10:19 Comment(0)
P
34

Try with this custom method:

public void parseVolleyError(VolleyError error) {
        try {
            String responseBody = new String(error.networkResponse.data, "utf-8");
            JSONObject data = new JSONObject(responseBody);
            JSONArray errors = data.getJSONArray("errors");
            JSONObject jsonMessage = errors.getJSONObject(0);
            String message = jsonMessage.getString("message");
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
        } catch (JSONException e) {
        } catch (UnsupportedEncodingException errorr) {
        }
    }

It will show toast with error message from the request. Call this in onErrorResponse method in your volley request:

new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                           parseVolleyError(error);
                        }
                    }
Planer answered 7/3, 2016 at 12:6 Comment(1)
for "utf-8", use StandardCharsets.UTF_8, this is to avoid using UnsupportedEncodingException catch block.Comb
P
10

The data field of networkResponse is a JSON string of the form:

{"response":false,"msg":"Old Password is not correct."}

So you need to get the value corresponding to "msg" field, like this (ofcourse with all exception catching):

String responseBody = new String(error.networkResponse.data, "utf-8");
JSONObject data = new JSONObject(responseBody);
String message = data.optString("msg");

Tested with Volley 1.1.1

Prognosticate answered 9/1, 2019 at 12:11 Comment(0)
C
2

IMO, you should override parseNetworkError as below:

@Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
    String json;
    if (volleyError.networkResponse != null && volleyError.networkResponse.data != null) {
        try {
            json = new String(volleyError.networkResponse.data,
                    HttpHeaderParser.parseCharset(volleyError.networkResponse.headers));
        } catch (UnsupportedEncodingException e) {
            return new VolleyError(e.getMessage());
        }
        return new VolleyError(json);
    }
    return volleyError;
}

Then, inside onErrorResponse(VolleyError error), you can use Log.e(LOG_TAG, error.toString()); for example. Hope it helps!

Cutright answered 8/3, 2016 at 1:28 Comment(1)
Thanks for your response, it helped!Lippi
S
1

you have to override parseNetworkError and deliverError methods and you can get errormessage from them.

Shopper answered 7/3, 2016 at 10:35 Comment(1)
Could you provide some code as an example? Not too sure how to do it.Lippi
S
1

Example to override methods :

final JsonObjectRequest request = new JsonObjectRequest(JsonObjectRequest.Method.POST,
            url, json,
            new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    TextView mTextView = (TextView) findViewById(R.id.output);
                    print("Success");
                }
            }, new Response.ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            TextView mTextView = (TextView) findViewById(R.id.output);
            print("Failure (" + error.networkResponse.statusCode + ")");
        }
    }){
        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            return super.parseNetworkError(volleyError);
        }

        @Override
        public void deliverError(VolleyError error) {
            super.deliverError(error);
        }
    };
Shopper answered 7/3, 2016 at 11:34 Comment(1)
Thanks for this, it helped :)Lippi
P
1

for get type error you can use this code

JsonArrayRequest request=new JsonArrayRequest(Request.Method.POST,Url,input,response ->{}  ,error -> {

 if (error instanceof TimeoutError) {
      //For example your timeout is 3 seconds but the operation takes longer
 }

 else if (error instanceof ServerError) {
        //error in server
 }

 else if (error instanceof NetworkError) {
        //network is disconnect
 }

 else if (error instanceof ParseError) {
        //for cant convert data
 }

 else {
        //other error
 }
 });

for get error message you can use this code

String Message=error.toString();
Protean answered 25/12, 2019 at 11:10 Comment(0)
M
1

For Kotlin, you can use this in your request class or singleton

 override fun parseNetworkError(volleyError: VolleyError): VolleyError {
            val json: String
            if (volleyError.networkResponse != null && volleyError.networkResponse.data != null) {
                    json = try {
                            String(volleyError.networkResponse.data,
                                    Charset.forName(HttpHeaderParser.parseCharset(volleyError.networkResponse.headers)))
                    } catch (e: UnsupportedEncodingException) {
                            return VolleyError(e.message)
                    }
                    return VolleyError(json)
            }
            return volleyError
    }
Mcgray answered 31/3, 2021 at 10:22 Comment(0)
M
0

Use this way

  Response.ErrorListener {

            var errorMsg =it.message

        }
Mcphail answered 18/10, 2022 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.