Wai Yan Hein
Wai Yan Hein

Reputation: 14831

Cannot retrieve error message from server in Error Listener of Volley in Android

I am developing an Android app. In my app, I am posting data to server via API using volley. But I am having a problem with retrieving error message from server and parsing it.

From server I am returning json data with Http status code 400 like this:

{
  "name":["name is required"],
  "email":["email is required"]
}

So when I make volley request to it, I am getting error with status code 400 as you can see in screenshot below.

enter image description here

What I want is, I want to parse that error message from server and show to user. I followed this link- Android: How handle message error from the server using Volley?

This is how I am making request and retrieving error message using volley

String url = LinkConfig.Register;
                JSONObject param = new JSONObject();
                param.put("name",tfName.getText().toString().trim());
                param.put("email",tfEmail.getText().toString().trim());
                param.put("password",tfPassword.getText().toString().trim());
                JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, param, new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        if(response!=null)
                        {
                            try{
                                String accessToken = response.getString("access_token");
                                User user = new User();
                                user.setId(response.getString("id"));
                                user.setName(response.getString("name"));
                                user.setEmail(response.getString("email"));
                                user.setAvatarUrl(response.isNull("avatar_url") ? null : response.getString("avatar_url"));
                                config.StoreUserCredentials(user, accessToken);
                                setResult(MainActivity.REGISTER_REQUEST_CODE);
                                finish();
                            }
                            catch (JSONException e)
                            {

                        }
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    NetworkResponse response = error.networkResponse;
                    String json = "";

                    if(response != null && response.data != null){
                        switch(response.statusCode){
                            case 400:
                                json = new String(response.data);
                                Toast.makeText(getBaseContext(),json,Toast.LENGTH_SHORT).show();
                                break;
                        }
                        //Additional cases
                    }
                }
            }){

                @Override
                protected VolleyError parseNetworkError(VolleyError volleyError) {
                    if(volleyError.networkResponse != null && volleyError.networkResponse.data != null){
                        VolleyError error = new VolleyError(new String(volleyError.networkResponse.data));
                        volleyError = error;
                    }

                    return volleyError;
                }
            };
            RequestSingleton.getInstance(getBaseContext()).addToRequestQueue(request);

But in above code, error.networkResponse is always null in onErrorResponse listener. Why is my code not working? Server is returning proper data and status code. How can I retrieve error message and parse it?

Upvotes: 1

Views: 1174

Answers (2)

BNK
BNK

Reputation: 24114

You can parse the error message if available by overriding parseNetworkError as the following:

@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;
}

Upvotes: 1

Jeevanandhan
Jeevanandhan

Reputation: 1073

We will get the error message as a byte array, we had to parse byte array and get the message. So, try this on error response

NetworkResponse networkResponse = error.networkResponse;
                String local = error.getLocalizedMessage();
                if (!TextUtils.isEmpty(local)) {
                    /** Error Message **/
                } else if (networkResponse != null) {

                    if (networkResponse.statusCode != 200) {
                        byte[] arr = networkResponse.data;
                       Toast.makeText(getBaseContext(),exceptionMessage(arr),Toast.LENGTH_SHORT).show();
                    }
                }

Below method will parse byte array and return as string,

/**
     * Converts the byte[] message to json object and send the exceptional message
     *
     * @param message error message in byte [] format.
     * @return error message in string format.
     */


    private String exceptionMessage(byte[] message) {
        String strMessage = new String(message);
        try {
            JSONObject jsonObject = new JSONObject(strMessage);
            if (jsonObject != null) {
                return jsonObject.optString("exceptionMessage");
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

Upvotes: 1

Related Questions