How to stop retrying request on 401 using volley and okhttp - android

I'm using the new(ish) volley library for networking in my app. The server I'm communicating with returns 401s sometimes without proper challenge headers and this can't be changed.
I started using OkHttp as the transport layer for volley because I actually needed to read the response and there was an exception being thrown when I got a 401. Now though anytime I receive a 401 the request is automatically retried once before it gets to my error listeners. This is problematic for me as the response in the 401 changes on the second request and that's the one I get access to.
Is there any way to change this so it doesn't retry automatically when you receive a 401, or alternatively get access to the response just using volley?

Implement own RetryPolicy and override public void retry(VolleyError error) method like this:
#Override
public void retry(VolleyError error) throws VolleyError {
if (error.networkResponse.statusCode == HttpStatus.SC_UNAUTHORIZED)
{
throw new VolleyError("Client is not authorized, retry is pointless");
}
}

Related

How to get response data on Android using Apollo client for GraphQL if http code is not 200?

I'm new to GraphQL using the Apollo client on Android. I'm trying to sign up a user on the server via graphQL mutation.
I call a mutation and if user's data is not valid I get http code 422: Unprocessible Entity, and in this case I cannot get any response details. I use standard way to make a call:
.enqueue(object : ApolloCall.Callback<CreateUserMutation.Data>() {
override fun onFailure(e: ApolloException) {
}
override fun onResponse(response:
Response<CreateUserMutation.Data>) {
}
And after this I'm in the onFailure block. ApolloException contains only http code description. But I want to see error details in a full response, that I can see via the Postman. I've already tried com.apollographql.apollo.ApolloCall.Callback#onHttpError callback, but the networkResponse body = null. I've described this problem here, but haven't fixed my problem:
https://github.com/apollographql/apollo-android/issues/1166
The way to do this is to check if ApolloException is an instanceof ApolloHttpException.
If it is, you can get the throwable.rawResponse().code() from it.
If it's not it means it isn't server error (maybe timeout or others)

How to send error message from node express to retrofit on android

I have a nodes server, and on my android device I'm using retrofit to talk to my API.
if I do a regular/succesfull response from server, res.json(User) or res.send("message"), I get the the response body on the android correctly.
public void onResponse(Call<User> call, Response<User> response) {
//response contains a body or message
}
HOWEVER, if I want to send an error, and use
res.status(500).json({"msg":"user not found");
or
res.status(500).send("user not found")
inside of my retrofit callback, I get a on success call back with the correct status code, in this case 500, but the error message I'm trying to send is not passed to me.
It seems that since the http response status was an error status, retrofit just ignores the response body/contents.
How can I send an error status 500, but also send data with it to retrofit?
I always use this approach:
res.send({status:200, "msg":"user not found"});

http status code even without error response retrofit

I'm working with Retrofit 1.9
I'm calling a webservice which never send response body, just a 200 when it's okey and a 404 when it's not.
To handle 202 success it's easy since the Retrofit callback already has a method "success" called when the code is between 200 and 300.
But the issue I have is with this part :
#Override
public void failure(RetrofitError error) {
error.getResponse().getStatus();
}
how should I get the http response code to check if it's a 404 or a 500(or whatever else) since the error.getResponse() is null ? I'm trying to do this to correctly notify the user.

Robospice caching when exception occured

I wan't to achieve next.
Depends on json content deside put or not to put data to Robospice Cache.
Sometimes data returned from the server is not valid. For example our authorization token goes off time. So we shouldn't cache this response.
But i can't find API which can help me to solve this trouble.
Here is how i am using requests now:
getSpiceManager().execute(getRequestCreator().getAllCategories(), getRequestCreator().getLastCacheKey(),
DurationInMillis.ONE_MINUTE * 120, new JSONCategoryListener(mCategories));
So the actual response is normal (status 200), but json content is telling me about exception.
So, what you want to get? It is right behavior for server. Server returns 200, means that request is successful. But it not guarantee, that wasn't some internal error of 'business logic' on server, such as not valid data or anything else.
EDITED
May be you can use your custom error handler:
class MyErrorHandler implements ErrorHandler {
#Override public Throwable handleError(RetrofitError cause) {
//check response on errors
}
}
And in createRestAdapterBuilder():
new RestAdapter.Builder()..setErrorHandler(new MyErrorHandler());
EDITED 2
You can implement in your robospice service method putDataInCache(Object cacheKey, T data), and in your listener check errors in content, and if no error then add it to cache, or remove it from cache

How do I get Robospice to treat anything other than a 200 response from Retrofit & OKHttp as an error

I am using Robospice on android with Retrofit and OKHttp. All works great with responses passed back to the activity using the Robospice RequestListener. The problem is that it only returns a failure if the connection times out or another network issue. If a 401 is returned then it is classed as a success but with a null response as it couldn't parse the JSON into our MobileAppSetup POJO.
At the moment I'm having to do null checking on the response but I have no idea what the reason was if it was a server error or a valid 401.
public final class HTTPRequestListener implements RequestListener<MobileAppSetup> {
#Override
public void onRequestFailure(SpiceException spiceException) {
Log.d("", "failure:"+ spiceException);
loginProgress.hide();
}
#Override
public void onRequestSuccess(final MobileAppSetup response) {
Log.d("","success. Data: "+response);
if(response==null)
showDialog("Error logging in", "Please check your username and password and try again.", "");
loginProgress.hide();
postLoginProcess(response);
}
}
I need to pass these errors to the onRequestFailure callback so I can properly handle it. Is there a way to specify error codes that Robospice should treat as an error. I think it involves adding some kind of custom error handler but really can't find a solution at the moment.
This due to the bug in OKHTTP client possible bug!
Problem is When the server answers with a 401 Unauthorized responses,
the Callback object calls its failure() method..
When the server returns with the 401 status, the RetrofitError
response object is null, and the networkError flag is set to true,
making it impossible for the app to check
error.getResponse().getStatus() I believe the error lies on the http
client. When using OkClient I get this error: java.io.IOException:
No authentication challenges found
I suggest you to download new okhttp jar file from square/okhttp run the project again! or try with any other client instead of okhttp.

Categories

Resources