Skip to content

Instantly share code, notes, and snippets.

@masihyeganeh
Created February 9, 2017 12:30
Show Gist options
  • Save masihyeganeh/45190bdde82e8e2cef3d09f4428f1753 to your computer and use it in GitHub Desktop.
Save masihyeganeh/45190bdde82e8e2cef3d09f4428f1753 to your computer and use it in GitHub Desktop.
Improved Retrofit Call

I just didn't like the way Retrofit is calling methods and I wanted to improve it. I believe error handling can be done much nicer. Here is what I did.

Preparing web service object to call remote methods:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://example.com/web-api/v1/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

WebService webService = retrofit.create(WebService.class);

Normal Retrofit web service call is like this:

webService.listShops().enqueue(new Callback<List<Shop>>() {
    @Override
    public void onResponse(Call<List<Shop>> call, Response<List<Shop>> response) {
        // response status handling and getting list of shops
    }

    @Override
    public void onFailure(Call<List<Shop>> call, Throwable t) {
        // error handling
    }
});

As you can see, we should handle response status and errors for every single call to web service. But with this class, you can have a single error handler for failures and other bad requests:

WebServiceCall webServiceCaller = new WebServiceCall(throwable -> {
    Log.e(TAG, throwable.getMessage());
});

webServiceCaller
        .call(webService.listShops())
        .then((List<Shop> response) -> {
            // do whatever you want with the list of shops. no response, just your object
        });

Or you can have no error handling at all!

WebServiceCall webServiceCaller = new WebServiceCall();

webServiceCaller
        .call(webService.listShops())
        .then((List<Shop> response) -> {
            // do whatever you want with the list of shops. no response, just your object
        });

Or you can handle errors of a specific call and let others be handled by the global error handler:

WebServiceCall webServiceCaller = new WebServiceCall(this);


webServiceCaller
        .call(webService.listPeople())
        .then((List<Person> response) -> {
            // do whatever you want with the list of people
        });

webServiceCaller
        .call(webService.listShops())
        .catches(throwable -> {
            // THIS SHOULD BE CALLED BEFORE "then" METHOD
            Log.e(TAG, throwable.getMessage());
        })
        .then((List<Shop> response) -> {
            // do whatever you want with the list of shops. no response, just your object
        });

webServiceCaller
        .call(webService.getShop(123))
        .then((Shop response) -> {
            // do whatever you want with the shop
        });
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
interface WebServiceHandler {
void onWebServiceError(Throwable throwable);
}
class WebServiceCall {
interface WebServiceCallback<T> {
void onResponse(T response);
}
class WebserviceCallbackHandler<T> {
private Call<T> call;
private WebServiceHandler tempHandler;
WebserviceCallbackHandler(Call<T> call) {
this.call = call;
}
void then(WebServiceCallback<T> callback) {
if (callback == null) return;
call.enqueue(new Callback<T>() {
@Override
public void onResponse(Call<T> call, Response<T> response) {
if (!response.isSuccessful()) {
throwError(new RuntimeException("Unsuccessful webservice call"));
}
else
callback.onResponse(response.body());
tempHandler = null;
}
@Override
public void onFailure(Call<T> call, Throwable t) {
throwError(t);
tempHandler = null;
}
});
}
private void throwError(Throwable t) {
if (tempHandler != null)
tempHandler.onWebServiceError(t);
else if (handler != null)
handler.onWebServiceError(t);
}
WebserviceCallbackHandler<T> catches(WebServiceHandler handler) {
this.tempHandler = handler;
return this;
}
}
private WebServiceHandler handler;
WebServiceCall() {
}
WebServiceCall(WebServiceHandler handler) {
this.handler = handler;
}
<T> WebserviceCallbackHandler<T> call(Call<T> call) {
return new WebserviceCallbackHandler<>(call);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment