I'm using Retrofit 2.0 along with RxJava and I need to make a custom error handler so that I can get the HTTP error code. This is the example that I get, but it won't work on Retrofit 2.0, since RetrofitError is removed.
#Override
public void onError(Throwable e) {
if (e instanceof RetrofitError) {
if (((RetrofitError) e).isNetworkError()) {
//handle network error
} else {
//handle error message from server
}
}
}
Is there any way that I can do this? Thanks.
I'm sorry that I didn't read the documentation carefully, so I just find a simple answer that works
#Override
public void onError(Throwable e) {
HttpException exception = (HttpException) e;
Toast.makeText(getApplicationContext(), exception.code() + "", Toast.LENGTH_SHORT).show();
}
Related
I can not subscribe to MQTT topic from my android application.
When i call SubscribeToTopic function, I get the following Error
"subscription to UserName/feeds/Topic failed: not available"
Here is the code to subscribe
private void SubscribeToTopic(String TopicName, int Qos) {
try {
if (client.isConnected()) {
client.subscribe(TopicName, Qos, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d("Subscribtion", "Succeed");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.d("Subscribtion", "Failed", exception);
}
});
}
}
catch (MqttException exception)
{
Log.d("Subscribtion","Failed",exception);
}
}
NOTE: I'm using Eclipse Paho as my MQTT Client and Adafruit IO as Broker. TopicName is something like UserName/feeds/Topic and Qos is 0
After spending hours finally found solution. There was no problem with code, I only changed the topic to public mode in Adafruit IO dashboard and it worked. The only thing i can not understand is why it is possible to subscribe to private topic from Arduino library but it fails in android.
My request should get either JSON for POJO or JSON described error(can be invalid request fields, server problems and so on).
But retrofit in subscriber gives me only Throwable. How can I find out is that a network error, what is http code, and get JSON with error?
private class ProjectListSubscriber extends Subscriber<ProjectListResponse> {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
//is that a network? http code? convert json to error POJO?
}
#Override
public void onNext(ProjectListResponse projectListResponse) {
updateProjectList(projectListResponse.getProjectList());
}
}
Since you are using RxJava, onError is called in case of network errors and endpoints related error are part of the Response.
In case of error, check if the throwable is an instance of HttpException
public void onError(Throwable e) {
if (e instanceof HttpException) {
if the check is true, the you have an error in your request. Cast the throwable to HttpException, and access is members. E.g.
((HttpException) e).response().errorBody()
if the check is false then you have a network related error.
I use Retrofit library to handle JSON response from my WCF web-service.
RestService.getRestService().search("tools", new Callback<SearchResult>() {
#Override
public void success(SearchResult searchResult, Response response) {
if( searchResult == null) return;
textView.setText(searchResult.toString());
} // end of success(
#Override
public void failure(RetrofitError error) {
showToast(R.string.internet_sikintisi);
}
});
I noticed that i get error if i leave the fragment or activity where i called this function from. Because I set text in textView where the activity or fragment is not already exists.
I modified the code to be like this:
RestService.getRestService().search("tools", new Callback<SearchResult>() {
#Override
public void success(SearchResult searchResult, Response response) {
if( searchResult == null) return;
try{
textView.setText(searchResult.toString());
} catch(Exception e) {}
} // end of success(
#Override
public void failure(RetrofitError error) {
try{
showToast(R.string.internet_sikintisi);
} catch(Exception e) {}
}
});
Basically, the problem solved, the app is not crashing every time the user gets in and out immediately. Still there might be a better solution for this problem.
I checked and Retrofit DOES NOT have cancel request feature!
You need to added checks success and failure methods the same way you would when using an asynctask check if the context still exist or make a isActive field that you set on onResume/onPause of the activity or fragment.
It is possible to cancel Retrofit requests in Retrofit 2(beta is available now.)
call.cancel();// as simple as that
I'm new in Robospice and I'm having a problem in handling error request. Is there a way that I can access the Response body from an error request in onRequestFailure method? If not, how you guys do it?
private class RequestListener implements RequestListener<Object> {
#Override
public void onRequestFailure(SpiceException e) {
}
#Override
public void onRequestSuccess(Object response) {
}
}
There's a suggestion that I should do the error checking inside the Spice Request. Any suggestion guys?
#Override
public SubscriptionsContainer loadDataFromNetwork() {
ResponseEntity<SubscriptionsContainer> response = null;
try {
response = getRestTemplate().exchange(/*your request data*/);
} catch (HttpClientErrorException e) {
String responsebody = e.getResponseBodyAsString();
}
}
If you throw any exception from loadDataFromNetwork(), it will be wrapped as SpiceException and passed to onRequestFailure() as its argument.
Therefore, you should check your ResponseEntity<T> for the conditions you expect and throw an exception in case those are not fulfilled.
If, on another hand, your RestTemplate.exchange call throws an exception, you could also handle it (as in your example) or let it be thrown (so it will be reported with onRequestFailure() on the main thread).
I am using Retrofit for both asynchronous and synchronous api calls.
For both I have a custom error handler defined to handle unauthorised responses. For the synchronous calls I have declared the custom exception on the interface methods, I surround the interface implementation with a try/catch and it works perfect. I can catch Unauthorised Exceptions.
I have tried the same with asynchronous calls that use a callback and it doesn't work the same. Instead of the catching the Exception in the try/catch, I have to handle it in the failure method of the callback.
Here is the interface method:
#GET("getGardenGnomes")
void getGardenGnomes(#Header("Authorisation") String authorisation, Callback<GardenGnomes> callback) throws UnauthorisedException;
Here is the implementation:
void onClick() {
try {
getGardenGnomes()
} catch (UnauthorisedException exception) {
// .... handle the exception ....
}
}
void getGardenGnomes() throws UnauthorisedException {
// .... get client etc etc ....
client.getGardenGnomes(authorisation, new Callback<GardenGnomes>() {
#Override
public void success(GardenGnomes gardenGnomes, Response response) {
// .... do something ....
}
#Override
public void failure(RetrofitError error) {
// .... handle error ....
}
}
);
}
The question is:
Should I just handle the exception in the failure(RetrofitError error) method of the Callback and don't declare throws UnauthorisedException on the interface method of asynchronous calls?
Or what is the best way to implement this?
The anwser is yes. Using Retrofit interfaces you don't declare which exception is thrown from the implementation on the interface. RetrofitError is a RuntimeException therefore unchecked. It's expected that a RetrofitError will be thrown on failures from the Retrofit implementation and you're responsible for handling it accordingly. Using synchronous method you simply use the try/catch as you mentioned. Using the asynchronous method you handle it in the failure callback method.
public void methodToHandleRetrofitError(RetrofitError error) {
// handle the error
}
// Synchronous
try {
client.getGardenGnomes(authorization)
} catch (RetrofitError e) {
methodToHandleRetrofitError(e);
}
// Asynchronous
client.getGardenGnomes(authorisation, new Callback<GardenGnomes>() {
#Override
public void success(GardenGnomes gardenGnomes, Response response) {
// .... do something ....
}
#Override
public void failure(RetrofitError error) {
methodToHandleRetrofitError(error);
}
}
);
Hope this clarifies things for ya!