Question

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.

Was it helpful?

Solution

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);
}

OTHER TIPS

You can combine the retrofit requests with an event bus and have a clean and centralised point for handling your responses.

All you need to do is define a Composed object like this:

public class GetUsers {
// Retrofit Request
public static final class Request {}

// Retrofit Callback
public static final class Callback 
      implements retrofit.Callback<Response response> {

    @Override
    public void success(Response response, 
         Response retrofitResponse) {
         // .... handle the code
         BusManager.post(new Event());
    }

    @Override
    public void failure(RetrofitError error) {}
         BusManager.post(new RetrofitErrorEvent(error));
    }

// Otto Event
public static final class Event {}

This object defines the Request, Callback and Event and this object is feed to the retrofit request.

 public void getUsers(){
     request.users(new GetUsers.Request(), new GetUsers.Callback());
 }

After this, in your main class looks like this:

public void onResume(){    
   controller.getUsers();
}

@Subscribe
public void onGetPostsEvent(GetPosts.Event event){
    textView.setText(event.getText());
}

For a more detailed explanation check this blog post: Otto + Retrofit – An elegant solution for Web Requests and you can find a working example here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top