Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using RoboSpice is there a way to get the HTTP Error Code out of an exception?

I am writing an application that uses RoboSpice. In the request listener onRequestFailure( SpiceException arg0 ) is there a way to know for sure that the error was a result of a 401 HTTP Error occurred?

I have a back end service, that returns a 401 error when a token expires, when that occurs I need to prompt the user to re-enter their credentials.

Is there anyway to know that a 401 HTTP error specifically occurred?

Below is an example of my request.

   public class LookupRequest extends SpringAndroidSpiceRequest <Product> {

public String searchText;
public String searchMode;

public LookupRequest() {
    super( Product.class );
}

@Override
public Product loadDataFromNetwork() throws Exception {
    String url = String.format("%s/Lookup?s=%s&m=%s", Constants.BASE_URL, searchText, searchMode);
    Ln.d("Calling URL: %s", url);
    return getRestTemplate().getForObject(url, Product.class );
}
like image 669
JLamkin Avatar asked Feb 13 '13 22:02

JLamkin


3 Answers

I looked over Spring-Android closer and it seems getRestTemplate().getForObject(...) throws a HttpClientErrorException when a 401 or any network error occurs.

Looking at the Robo Spice for where they catch that exception I found they catch it in RequestProcessor.java in the processRequest function. They pass the Spring-Android exception in as the throwable inside their SpiceException that inherits from Java exception class.

So you just do the following inside your RoboSpice RequestListener to see if it a 401 UNAUTHORIZED exception.

    private class MyRequestListener implements RequestListener<RESULT> {

    public void onRequestFailure( SpiceException arg0 ) {

        if(arg0.getCause() instanceof HttpClientErrorException)
        {
            HttpClientErrorException exception = (HttpClientErrorException)arg0.getCause();
            if(exception.getStatusCode().equals(HttpStatus.UNAUTHORIZED))
            {
                Ln.d("401 ERROR");
            }
            else
            {
                Ln.d("Other Network exception");
            }
        }
        else if(arg0 instanceof RequestCancelledException)
        {
            Ln.d("Cancelled");
        }
        else
        {
            Ln.d("Other exception");
        }
    };

    public void onRequestSuccess( RESULT result ) {
        Ln.d("Successful request");
    }
}
like image 77
JLamkin Avatar answered Oct 30 '22 08:10

JLamkin


I am using the google http client with RoboSpice and has the same issue but was easy to solve with request.setThrowExceptionOnExecuteError(false); and checking the response code on the resulting HttpResponse object

EDIT: the code snippit as requested

HttpRequest request = getHttpRequestFactory().buildPostRequest(new GenericUrl(URL), content);
request.setThrowExceptionOnExecuteError(false);
HttpResponse response = request.execute();

switch(response.getStatusCode())
    {
        case HttpStatusCodes.STATUS_CODE_UNAUTHORIZED:
            return new MyBaseResponse(responseBody);
        default:
            throw new RuntimeException("not implemented yet");
    }
like image 45
Dori Avatar answered Oct 30 '22 07:10

Dori


For those who can't resolve HttpClientErrorException into a type, and cannot find any documentations online, (that's me), here is my approach:

In my fragment, here is my listener:

private final class MyRequestListener extends RequestListener<MyResponse> {

  @Override
  public void onRequestFailure(SpiceException spiceException) {
    super.onRequestFailure(spiceException);
    if (spiceException instanceof NetworkException) {
      NetworkException exception = (NetworkException) spiceException;
      if (exception.getCause() instance RetrofitError) {
        RetrofitError error = (RetrofitError) exception.getCause();
        int httpErrorCode = error.getResponse().getStatus();
        // handle the error properly...
        return;
      }
    }
    // show generic error message
  }

}

Hope this maybe helpful to someone.

I would move the whole if clause into a static function so it can be reused. Just return 0 if exception doesn't match. And I haven't verify if any of the casting can be removed...

like image 2
John Pang Avatar answered Oct 30 '22 06:10

John Pang