I'm using Volley StringRequest to post a query to my server and I seeing that in about 20% of cases, the request is successful but onErrorResponse is called instead of onResponse.
Here is my request code:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("App", "[MainActivity] post successful");
// run very important routine only when post is successful
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("App", "[MainActivity] failed to post");
if (error == null) {
Log.e("App", "no error");
}
else if (error.networkResponse != null) {
Log.e("App", String.valueOf(error.networkResponse.statusCode));
if(error.networkResponse.data != null) {
try {
Log.e("App", new String(error.networkResponse.data, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
else {
Log.e("App", "no network response");
}
}
});
requestQueue.add(stringRequest);
20% of the time I see:
E/App: [MainActivity] failed to post
E/App: no network response
but in my server logs I see a 200 message and the data created by the post is in my database.
Why would Volley throw an error on a successful post?
UPDATE
Log.e("App", "error message: " + error.getMessage());
prints: E/App: error message: null
What is the error message returned by volley? Check it by volleyError.getMessage().
Related
here is for several days I block on a proleme. I have to send a post request with json data to a server and I try this:
private void sendRequestInfo() {
JSONObject json = new JSONObject();
try {
json.put("email", "test#gmail.com");
json.put("password", "abcd");
} catch (JSONException e) {
e.printStackTrace();
}
mRequestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, json,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
resultOne.setText(response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
resultOne.setText(error.toString());
}
});
mRequestQueue.add(jsonObjectRequest);
}
communication with the server seems to be done since node brings out this line:
Executing (default): SELECT id, username, password, services, createdAt, updatedAt FROM users AS users WHERE users.username = 'register#gmail.com' LIMIT 1;
but I have this error:
"Value Logged of type java.lang.String cannot be converted to JSONObject"
normally the node server should send me back "user not found" I do not understand this error if someone can help me.
I am using the strava API for an app. I am making synchronous requests as can be seen by the code below.
try {
RequestQueue queue = Volley.newRequestQueue(context);
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest request = new StringRequest(Request.Method.GET, urlRequest, future, future);
queue.add(request);
dataResponse = dealWithResponse(future.get());
} catch (ExecutionException e) {
System.err.println(e.getLocalizedMessage());
System.err.println(e.getMessage());
System.err.println(e.toString());
} catch (java.lang.Exception e) {
e.printStackTrace();
}
I want to know how can I get the response code in the event of an error? for example some rides I request have been deleted / are private and i receive a 404 error code. Other times I have run out of API requests and get a code of 403. How can i differentiate between the thrown errors.
Thank you very much for your help!
In your catch clause, where you handle the ExecutionException you can add the following:
if (e.getCause() instanceof ClientError) {
ClientError error = (ClientError)e.getCause();
switch (error.networkResponse.statusCode) {
//Handle error code
}
}
Override parseNetworkError on your request:
StringRequest request = new StringRequest(Request.Method.GET, urlRequest, future, future) {
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
if (volleyError != null && volloeyError.networkResponse != null) {
int statusCode = volleyError.networkResponse.statusCode;
switch (statusCode) {
case 403:
// Forbidden
break;
case 404:
// Page not found
break;
}
}
return volleyError;
}
};
I developed a service, using resttemplate and using this service(clientproject) in another project(server), I am trying to throw the exception from resttemplate and handle at server project,but it is not working.
Here is my code:
public class UserService{
public long createUser(Long servcieId){
long userId =0L;
try
{
response = restTemplate.exchange(url,HttpMethod.POST, request, Object.class);
userId = response.getBody().getUser().getId();
}
catch(RestClientException e){
throw e;
}
return userId;
}
}
Here is my service code:
public Long createUserInPortal(Long serviceId){
try
{
Long userId=userService.createUser(serviceId);
}
catch(RestClientException e){
if(e instanceof HttpStatusCodeException){
String errorResponse=((HttpStatusCodeException)e).getResponseBodyAsString();
logger.error("the error in user service is:"+errorResponse);
}
}
I am getting the following error,"resulted in 422 (Unprocessable Entity); invoking error handler".
I am trying to see the response string in the catch block but it is not reaching this catch block.
well may be its getting inside catch block but gets filtered by
if(e instanceof HttpStatusCodeException){ condition
May be e instance is not of type HttpStatusCodeException there are other possibilities like
} catch (HttpClientErrorException e) {
success = false;
Log.e(TAG, command+" was rejected for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (HttpServerErrorException e) {
success = false;
Log.e(TAG, command+" could not be completed for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (ResourceAccessException e) {
if (attemptsLeft > 0) {
Log.w(TAG, command+" failed I/O, retrying.", e);
return simplePut(baseUrl, url, b, command, payload, attemptsLeft);
}
success = false;
Log.e(TAG, command+" failed I/O for URL: "+url, e);
resultCode = 499;
} catch (RestClientException e) {
success = false;
Log.e(TAG, command+" failed for URL: "+url, e);
resultCode = 599;
}
I am attempting to use the Okhttp library to connect my android app to my server via API.
My API call is happening on a button click and I am receiving the following android.os.NetworkOnMainThreadException. I understand that this is due the fact I am attempting network calls on the main thread but I am also struggling to find a clean solution on Android as to how make this code use another thread (async calls).
#Override
public void onClick(View v) {
switch (v.getId()){
//if login button is clicked
case R.id.btLogin:
try {
String getResponse = doGetRequest("http://myurl/api/");
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
String doGetRequest(String url) throws IOException{
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
Above is my code, and the exception is being thrown on the line
Response response = client.newCall(request).execute();
I've also read that Okhhtp supports Async requests but I really can't find a clean solution for Android as most seem to use a new class that uses AsyncTask<>?
To send an asynchronous request, use this:
void doGetRequest(String url) throws IOException{
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request)
.enqueue(new Callback() {
#Override
public void onFailure(final Call call, IOException e) {
// Error
runOnUiThread(new Runnable() {
#Override
public void run() {
// For the example, you can show an error dialog or a toast
// on the main UI thread
}
});
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
String res = response.body().string();
// Do something with the response
}
});
}
& call it this way:
case R.id.btLogin:
try {
doGetRequest("http://myurl/api/");
} catch (IOException e) {
e.printStackTrace();
}
break;
I am using the great async http library from loopj, but I have run into a small snag.
If the user has no internet connection or loses their connection, the app just won't return anything. This part is expected, but it also doesn't fire the onFailure method.
Also, the code I have used when there is an internet connection does work so there is no problem on the server end.
Here is some code that is stripped down to the minimum. It also doesn't work (I have tested this too)
String url = getString(R.string.baseurl) + "/appconnect.php";
client.getHttpClient().getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
client.get(url, null, new JsonHttpResponseHandler()
{
#Override
public void onSuccess(JSONArray response)
{
Toast.makeText(getApplicationContext(), "Success", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Throwable e, JSONArray errorResponse)
{
Toast.makeText(getApplicationContext(), "Failure", Toast.LENGTH_SHORT).show();
}
});
Thanks,
Ashley
You can try this:
In AsyncHttpRequest->makeRequestWithRetries(), add a catch to SocketException like this:
while (retry) {
try {
makeRequest();
return;
} catch (UnknownHostException e) {
if(responseHandler != null) {
responseHandler.sendFailureMessage(e, "can't resolve host");
}
return;
} catch (SocketException e){
// Added to detect no connection.
if(responseHandler != null) {
responseHandler.sendFailureMessage(e, "can't resolve host");
}
return;
} catch (IOException e) {
cause = e;
retry = retryHandler.retryRequest(cause, ++executionCount, context);
} catch (NullPointerException e) {
// there's a bug in HttpClient 4.0.x that on some occasions causes
// DefaultRequestExecutor to throw an NPE, see
// http://code.google.com/p/android/issues/detail?id=5255
cause = new IOException("NPE in HttpClient" + e.getMessage());
retry = retryHandler.retryRequest(cause, ++executionCount, context);
}
}
Yeah, unfortunately the loopj Android library isn't very well designed. If you implement the other onFailure callbacks one of them should fire:
#Override
public void onFailure(Throwable e) {
Log.e(TAG, "OnFailure!", e);
}
#Override
public void onFailure(Throwable e, String response) {
Log.e(TAG, "OnFailure!", e);
}
#Override
public void onFailure(Throwable e, JSONArray errorResponse) {
Log.e(TAG, "OnFailure!", e);
}
Try this:
#Override
protected Object parseResponse(byte[] responseBody) throws JSONException {
return super.parseResponse(responseBody);
}