Ma7moud El-Naggar Ma7moud El-Naggar - 1 year ago 110
Android Question

Retrofit and Centralized Error Handling

Each request to the server may return

. I want to handle these error in one place
when I was using AsyncTask I had a BaseAsyncTask like that

public abstract class BaseAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {

protected Context context;
private ProgressDialog progressDialog;
private Result result;

protected BaseAsyncTask(Context context, ProgressDialog progressDialog) {
this.context = context;
this.progressDialog = progressDialog;

protected void onPreExecute() {

protected void onPostExecute(Result result) {
HttpResponse<ErrorResponse> response = (HttpResponse<ErrorResponse>) result;
if(response.getData().getErrorCode() != -1) {


private void handleErrors(ErrorResponse errorResponse) {
public abstract void onResult(Result result);

But, using retrofit each request has its error handling callback:

git.getFeed(user,new Callback<gitmodel>() {
public void success(gitmodel gitmodel, Response response) {


public void failure(RetrofitError error) {


How can I handle all errors in one place?

Answer Source

If you need to get some 'logic' error, then you need some Java logic since it's not a Retrofit feature so basically:

  1. Create a Your implementation Callback that implements the Retrofit Callback
  2. Create a base object that define the method 'isError'
  3. Modify Retrofit RestAdapter in order to get your Callback instead of the Retrofit One

import android.util.Log;
import retrofit.Callback;
import retrofit.client.Response;

public abstract class MyCallback<T extends MyObject> implements Callback<T> {

    public final void success(T o, Response response) {
        if (o.isError()) {
            // [ something with error]
        else {
            handleSuccess(o, response);

    abstract void handleSuccess(T o, Response response);

    void handleLogicError(T o) {
        Log.v("TAG", "Error because userId is " +;
} (the base class for all your objects you get from Retrofit)

public class MyObject {
    public long id;
    public boolean isError() {
        return id == 1;
} - a class that extends the base object

public class MyRealObject extends MyObject {
    public long userId;
    public String title;
    public String body;
} - the interface used by retrofit you should be familiar with

import retrofit.http.GET;
import retrofit.http.Path;

public interface RetroInterface {

    void sendGet(@Path("id") int id, MyCallback<MyRealObject> callback);


And finally the piece of code where you use all the logic

    RestAdapter adapter = new RestAdapter.Builder()

    RetroInterface itf = adapter.create(RetroInterface.class);
    itf.sendGet(2, new MyCallback<MyRealObject>() {
        void handleSuccess(MyRealObject o, Response response) {
            Log.v("TAG", "success");

        public void failure(RetrofitError error) {
            Log.v("TAG", "failure");

If you copy and paste this code, you'll get an error when you'll execute the itf.sendGet(1, new MyCallback..) and a success for itf.sendGet(2, new MyCallback...)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download