Retrofit: Http status code callbacks

Created on 8 Mar 2015  路  3Comments  路  Source: square/retrofit

First of all, thanks for the library! It's amazing how fast we can code with it.

Second. I think it could be very helpful in sometime with we have a callback class that have methods based on the HTTP status codes.

For now i'm filtering with switches inside

SomeSaaS.api.getSomething(new Callback<ArrayList<String>>() {

            @Override public void success(ArrayList<String> strings, Response response) {
                switch (response.getStatus()){
                    case 200:{
                        break;
                    }

                }
            }

            @Override public void failure(RetrofitError error) {
                switch (response.getStatus()){
                    case 404:{
                        break;
                    }
                    case 401:{
                        break;
                    }
                }
            }
        });

So what i'm proposing is

SomeSaaS.api.getSomething(new CallbackPerCode<ArrayList<String>>() {

            @Override public void on200(ArrayList<String> strings, Response response) {

            }

            @Override public void on401(RetrofitError error) {

            }
            @Override public void on404(RetrofitError error) {

            }
        });

This could be useful, or am i just dreaming? Thanks :)

Most helpful comment

Your example is too application-specific for everyone. But you can do this yourself with an abstract base class:

public abstract class CallbackPerCode<T> implements Callback<T> {
  public abstract void on200(T value, Response response);
  public abstract void on401(RetrofitError error);
  public abstract void on404(RetrofitError error);

  public final onSuccess(T value, Response response) {
    on200(value, response);
  }

  public final onFailure(RetrofitError error) {
    switch (error.getKind()) {
      case NETWORK:
        // TODO something
        break;
      case UNEXPECTED:
        throw error;
      case HTTP:
        Response response = error.getResponse();
        switch (response.getCode()) {
          case 401:
            on401(error);
            break;
          case 404:
            on404(error);
            break;
          default:
            throw error;
        }
        break;
       default:
        throw new IllegalStateException("Unknown error kind: " + error.getKind(), error);
    }
  }
}

All 3 comments

Your example is too application-specific for everyone. But you can do this yourself with an abstract base class:

public abstract class CallbackPerCode<T> implements Callback<T> {
  public abstract void on200(T value, Response response);
  public abstract void on401(RetrofitError error);
  public abstract void on404(RetrofitError error);

  public final onSuccess(T value, Response response) {
    on200(value, response);
  }

  public final onFailure(RetrofitError error) {
    switch (error.getKind()) {
      case NETWORK:
        // TODO something
        break;
      case UNEXPECTED:
        throw error;
      case HTTP:
        Response response = error.getResponse();
        switch (response.getCode()) {
          case 401:
            on401(error);
            break;
          case 404:
            on404(error);
            break;
          default:
            throw error;
        }
        break;
       default:
        throw new IllegalStateException("Unknown error kind: " + error.getKind(), error);
    }
  }
}

Wow. Thanks!

Anyone who wanna use this will be thinking about the abstract behavior and agree with @JakeWharton about the specific-application context. So i removed it to the class reach what i want: Flexibility, Fragmentation, Organization.

package vyscond.infosae.rest;

import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;

public abstract class CallbackPerCode<T> implements Callback<T> {

    public void on200(T value, Response response){

    };

    public void on400(RetrofitError error){

    };

    public void on401(RetrofitError error){

    };

    public void on403(RetrofitError error){

    };

    public void on404(RetrofitError error){

    };


    public void onNetworkError(RetrofitError error){

    };

    public final void onSuccess(T value, Response response) {

        on200(value, response);
    }

    public final void onFailure(RetrofitError error) {

        switch (error.getKind()) {
            case NETWORK:
                onNetworkError(error);
                break;
            case UNEXPECTED:
                throw error;
            case HTTP:
                Response response = error.getResponse();
                switch (response.getStatus()) {
                    case 400:
                        on400(error);
                        break;
                    case 401:
                        on401(error);
                        break;
                    case 403:
                        on403(error);
                        break;
                    case 404:
                        on404(error);
                        break;
                    default:
                        throw error;
                }
                break;
            default:
                throw new IllegalStateException("Unknown error kind: " + error.getKind(), error);
        }
    }
}

The only problem remaining is how can be possible to preserver the "original" name of the response Object like it happen on the canonical callback class.

Was this page helpful?
0 / 5 - 0 ratings