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
Related
So I have these two parallel calls using zip operator. I am making two network calls. I have the following questions:
How can I handle the individual errors correctly
If the first call fails I want to be able to exit the session but if the second network call fails I want to allow the user to still go through the session. I am seeing a 404 in my second network call in the zip and the entire chain fails with an error. I want it to be able to handle success and failure
valid session
response 1: success
response 2: failure
invalid session
response 1: failure
response 2: success
invalid session
both endpoints fail
Single.zip(
api1.getData().doOnError {
// handle error : exit right away
},
api2.getData().doOnError {
// handle error: Set profile data to be empty but when user tries to see the profile information show error at a later point in time based oaths response
// got 404
},
{ response1: String, response2: CustomObject ->
Pair(response1, response2)
}
)
.subscribeOn(Schedulers.io())
.subscribe(
{
handleResponse1(it.first)
handleRespone2(it.second)
},
{
Timber.d("it : $it")
// api1 use success response: is it even possibel to get that in the iterator
// api 2 throwing 404 here
}
)
From your question, I see that you want to continue even if one of the API fails without failing the whole chain. This can be done in the following way
If you want to exit on the first API call no need to handle any Error there.(You will get an error in throwable)
Whenever the second API fails use onErrorReturnItem to return some empty response
Single.zip(
api1.getData().subscribeOn(Schedulers.io()),
api2.getData().subscribeOn(Schedulers.io())
.onErrorReturnItem(new Response())
.......
The new Response() here is just an empty object of the response of type that you were expecting. Even if the second API fails here you will get whatever you are returing
If the first API fails here you will get a callback in Throwable or you can continue to handle error in doOnError
I have seen other threads for this issue but unable to get any proper answer.
#POST("task/GetAllTasks")
Call<MyTask> getMyTasks(#Header("Authorization") String token, #Query("EmployeeId") String emp);
This is how I am calling, at first I thought it is due to GET request data limitation because GET imposes data limits and then I changed request from GET to POST but issue still persists.
ApiUtils.getTaskService().getMyTasks(apiToken, employeeId).enqueue(new Callback<MyTask>() {
#Override
public void onResponse(Call<MyTask> call, Response<MyTask> response) {
// ... Successful code goes here
}
#Override
public void onFailure(Call<MyTask> call, Throwable t) {
//.. This block of code executing now :(
}
}
Always onFailure is being called. I have tested this same request on Postman and it is returning data. Content-Length is content-length →45720
It does work on small amount of data as I have tested it on Dev database which has smaller amount of data but on Live environment it is continuously causing problem.
Please suggest a solution or should I leave Retrofit and move to native Android library for this?
EDIT: Can we increase request timeout in Retrofit, if yes then how?
Try to increase your timeout:
OkHttpClient client = new OkHttpClient().newBuilder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS).build();
And set it to your retrofit:
new Retrofit.Builder().baseUrl("xxx").client(client).build().create(xxx.class);
Use #Part to send big string data it can easily send your data to server side
For ex.
You need to send some string that name is "abc" then in the retrofit code
#Part("abc") //your string variable
Its works for me and I save that data to mediumtext in mysql
and the code is $_REQUEST['abc'];
I have tried to use retrofit 2.1.0 for my image upload call in multipart. But the issue that i m facing is call is requested so server side the update is done but in the way of response if internet connection gets off it jumps to onFailure() method even though call was successful.Hope you understand my issue here.Please help me to solve this.Your help will be appreciated.
In case that happens make the user try again..... in the application side send a tag with the file like presentFileTag and in the server side ``
if(previousFileTag.equals(presentFileTag)
{
if(fileUploaded)
{
//send response file already present or posetive response
}
else
{
//Store the file
}
}
else
{
//Store the file
}
I've created my own request and in the constructor I set setShouldCache(Boolean.TRUE); .
When the request is called for the first time (no cache is used) then all is good and I can see the content being cached. Second time I call the same URL a bizarre thing happens:
else {
// Insert 'null' queue for this cacheKey, indicating there is now a request in
// flight.
mWaitingRequests.put(cacheKey, null);
mCacheQueue.add(request); <-- being called
Extracted from RequestQueue.add.
I can see in the debugger that mCacheQueuefills up, but nothing is being called from it, .e.g
// Take a request from the queue.
request = mCacheQueue.take();
Extracted from CacheDispatcher.run.
is stuck.
This is the piece of code that creates the request:
RequestFuture<String> future = _requestFutureProvider.get();
FetchArticleImageRequest request = new FetchArticleImageRequest(pageId,
300,
future, future);
_requestQueue.add(request);
try {
// this will never block
imgUrl = future.get(3, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("Unable to fetch img url", e);
}
One more piece of information, I'm running the request inside parseQueryResponse of another request, so it does not run in the main thread.
BTW when not using cache all is working well (e.g. requests are being made against the server).
Any idea what is going here?
Ok, Tx to our buddies in google groups (Ficus Kirkpatrick) there is an answer.
It happened because I ran a Future request inside another request which ran as part of the cache dispatcher. My solution was to remove caching from the request that dispatched the other requests.
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.