Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch http response in Retrofit before passing it to the calling activity

Right now we are using retrofit like this:

service.executeSomeRequest(UserPreferenceRequest userPreferenceRequest, new Callback<UserPreferenceResponse>() {
    @Override
    public void success(UserPreferenceResponse responseCallback, Response response) {
        if (responseCallback.getStatus() == ResponseStatus.OK) {
            // Everything is OK, process response
        } else {
            ApiErrorProcessor.process(responseCallback.getError());
        }
    }

    @Override
    public void failure(RetrofitError retrofitError) {
        ServerErrorProcessor.process(retrofitError);
    }
});

But we have a lot of requests, and practically, every request we implement requires us to write the same error code handling (for API, and server errors) which duplicates the code.

What we want is to override only methods of interest, and if no implementation provided then a default implementation to be executed.

Something like this:

service.executeSomeRequest(UserPreferenceRequest userPreferenceRequest, new     
    CustomCallback<UserPreferenceResponse>() {
            @Override
            public void success(UserPreferenceResponse responseCallback, Response response) {
                super.success(responseCallback, response);
                // Everything is OK, process response
            }
    });

The CustomCallback will take care of API and server errors, and if everything is OK, then only then pass the result to the calling activity.

When building the RestAdapter there is setRequestInterceptor(); which allows me to catch the request before issuing it, I was thinking of something similar, like setResponseInterceptor(), that will allow me to catch the response before passing it to the activity and treat there generic errors, but didn't find something similar.

like image 470
Andy Res Avatar asked Apr 30 '14 08:04

Andy Res


1 Answers

Your custom callback can process the response in the base class first and then delegate to an abstract method.

public interface StatusResponse {
  Status getStatus();
}

public abstract class CustomCallback<T extends StatusResponse> implements Callback<T> {
  @Override public final void success(T data, Response response) {
    if (data.getStatus() == Status.OK) {
      success(data);
    } else {
      // Handle error..
    }
  }

  public abstract void success(T data);
}
like image 135
Jake Wharton Avatar answered Oct 11 '22 11:10

Jake Wharton