Implementing my LoginActivity.java, I setup another file+class
called AuthClient
which uses Volley heavily. UserLoginTask
needs to return a Boolean
from its doInBackground
so that the remote call to login succeeds/fails.
So following Can I do a synchronous request with volley?, I setup:
void login(final HashMap<String, String> data,
Response.Listener<JSONObject> listener,
Response.ErrorListener errorListener) {
JsonObjectRequest req = new JsonObjectRequest(
api_prefix + "/auth", new JSONObject(data), listener, errorListener
);
queue.add(req); // RequestQueue
}
boolean loginResponseHandler(RequestFuture<VolleyError> err_future,
RequestFuture<JSONObject> future) {
try {
VolleyError err_response = err_future.get();
JSONObject response = future.get();
System.out.println("response.toString() = " + response.toString());
return true;
} catch (InterruptedException | ExecutionException e) {
System.err.println("e = " + e.toString());
return false;
} catch (Exception e) { // Even tried this!
System.err.println("Exception::e = " + e.toString());
throw e;
}
}
@Override
protected Boolean doInBackground(Void... params) {
RequestFuture<JSONObject> future = RequestFuture.newFuture();
RequestFuture<VolleyError> err_future = RequestFuture.newFuture();
login(/*omitted for brevity*/, err_future, future);
return loginResponseHandler(err_future, future);
} // Actual code has login/loginResponseHandler in separate class+file, and more^
But looking at the debug log, I get the error (from somewhere else, not where I'm debugging):
08-24 23:17:13.228 7255-7288 E/Volley: [177] BasicNetwork.performRequest: Unexpected response code 400 for http://192.168.5.3:3003/v1/api/auth
How am I meant to handle errors? - Also is there a reference scaffold to work from?
first of all
VolleyError err_response = err_future.get();
it is not good if the request does not have an error you will get some cast exception.
actually you don't need 2 Futures as RequestFuture implements both Response and Error Listeners.
So to the point.
future.get()
returns the Result. If an error occurs then it throws and Execution exception which could containf VolleyError exception, which may contain some network data if any is received. All you need to do is to cast to inner excetion to VolleyError and get the data in your catch statement.
try {
JSONObject response = future.get();
System.out.println("response.toString() = " + response.toString());
return true;
} catch (InterruptedException | ExecutionException e) {
if (VolleyError.class.isAssignableFrom(e.getCause().getClass())) {
VolleyError ve = (VolleyError) e.getCause();
System.err.println("ve = " + ve.toString());
if (ve.networkResponse != null) {
System.err.println("ve.networkResponse = " +
ve.networkResponse.toString());
System.err.println("ve.networkResponse.statusCode = " +
ve.networkResponse.statusCode);
System.err.println("ve.networkResponse.data = " +
new String(ve.networkResponse.data));
return false;
}
}
}
Update
As regards to 'the best client design' it depends on the app design choices you have made. However there few important things for errors you must know:
Errors can be 3 main types: protocol/network errors with network response or without and other errors purely java and related to handling request/response the most common of which is parsing data.
There 2 main approaches to handle errors having that they are not coming from your code.
Normally you may use the first one for some network and 5xx errors and then have some message handler to let the user know hat has happened.
Again, how you implement this really depends on your app architecture. I personally use a a lot rxJava and apply some kind of data flow design where I got all the errors coming in one place and then decide what to do with them depending on the request, the error itself and app state.
For my apps I use jus(highly extended volley) with rx-jus module and RxQueueHub class based on rxHub so i get all the responses and errors in one place available to all my handlers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With