Android: How handle message error from the server using Volley?
I've implemented something similar to this, and it's relatively simple. Your log message is printing out what looks like gibberish, because response.data
is really a byte array - not a String
. Also, a VolleyError
is really just an extended Exception
, so Exception.getMessage() likely wouldn't return what you are looking for unless you override the parsing methods for parsing your VolleyError
in your extended Request
class. A really basic way to handle this would be to do something like:
//In your extended request class
@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;
}
}
If you add this to your extended Request
classes, your getMessage()
should at least not return null. I normally don't really bother with this, though, since it's easy enough to do it all from within your onErrorResponse(VolleyError e)
method.
You should use a JSON library to simplify things -- I use Gson for example or you could use Apache's JSONObject
s which shouldn't require an additional external library. The first step is to get the response JSON sent from your server as a String
(in a similar fashion to what I just demonstrated), next you can optionally convert it to a JSONObject (using either apache's JSONObject
s and JsonArray
s, or another library of your choice) or just parse the String
yourself. After that, you just have to display the Toast
.
Here's some example code to get you started:
public void onErrorResponse(VolleyError error) {
String json = null;
NetworkResponse response = error.networkResponse;
if(response != null && response.data != null){
switch(response.statusCode){
case 400:
json = new String(response.data);
json = trimMessage(json, "message");
if(json != null) displayMessage(json);
break;
}
//Additional cases
}
}
public String trimMessage(String json, String key){
String trimmedString = null;
try{
JSONObject obj = new JSONObject(json);
trimmedString = obj.getString(key);
} catch(JSONException e){
e.printStackTrace();
return null;
}
return trimmedString;
}
//Somewhere that has access to a context
public void displayMessage(String toastString){
Toast.makeText(context, toastString, Toast.LENGTH_LONG).show();
}
Volley error output the error message sent from server side
Try this way to read Response from NetworkResponse
For kotlin
val response = er.networkResponse
val jsonError = String(response.data)
val responseObject = JSONObject(response)
val message = responseObject.optString("message")
for java
NetworkResponse response = er.networkResponse;
String responseData = new String(response.data,"UTF-8");
JSONObject responseObject =new JSONObject(response)
String message = responseObject.optString("message")
Cannot retrieve error message from server in Error Listener of Volley in Android
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;
}
Handle Volley error
The networkResponse is null because in a TimeoutError no data is received from the server -- hence the timeout. Instead, you need generic client side strings to display when one of these events occur. You can check for the VolleyError's type using instanceof to differentiate between error types since you have no network response to work with -- for example:
@Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Toast.makeText(context,
context.getString(R.string.error_network_timeout),
Toast.LENGTH_LONG).show();
} else if (error instanceof AuthFailureError) {
//TODO
} else if (error instanceof ServerError) {
//TODO
} else if (error instanceof NetworkError) {
//TODO
} else if (error instanceof ParseError) {
//TODO
}
}
How to get error message description using Volley
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);
}
}
Handle a 401 error in Volley's onErrorResponse listener
You can handle this in either of this below ways,
Handle the lost internet signal in your app and navigate to a different page (search for how to handle no internet, lot of articles available)
Surround JsonObjectRequest call in try catch and handle the exception on your own
How to access the contents of an error response in Volley?
In StringRequest for example:
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
Map<String, String> responseHeaders = response.headers;
if (response.statusCode == 401) {
// Here we are, we got a 401 response and we want to do something with some header field; in this example we return the "Content-Length" field of the header as a successfully response to the Response.Listener<String>
Response<String> result = Response.success(responseHeaders.get("Content-Length"), HttpHeaderParser.parseCacheHeaders(response));
return result;
} // else any other code that carries a message
return super.parseNetworkResponse(response);
}
Related Topics
How to Configure Launcher Activity Programmatically in Android
Android 'Debuggable' Default Value
Nexus 5X Reverse Landscape Sensor Fix in a Android Camera Preview App
Disable Home Button in Android Ics (4.0)
Android - Detecting Application Launch from Home or History
Bitmap Too Large to Be Uploaded into a Texture
Mpandroidchart - Adding Labels to Bar Chart
Speed Up 'Navigation Drawer' Animation Speed on Closing
How to Detect Android CPU Speed
Broadcast Receiver Not Working in Android Oreo
Can Not Set Debuggable Flag in Androidmanifest.Xml
Limitation on Texture Size? Android Open Gl Es 2.0
How to Use Asynctask to Display a Progress Bar That Counts Down
How to Make Zoomable Linearlayout
Android: Get Facebook Friends List