Retrofit - Intercept responses globally

OkHttpClient okHttpClient = new OkHttpClient.Builder()  
    .addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            okhttp3.Response response = chain.proceed(request);

            // todo deal with the issues the way you need to
            if (response.code() == 500) {
                startActivity(
                        new Intent(
                                ErrorHandlingActivity.this,
                                ServerIsBrokenActivity.class
                        )
                );

                return response;
            }

            return response;
        }
    })
    .build();

Retrofit.Builder builder = new Retrofit.Builder()  
        .baseUrl("http://your_url")
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create());

Retrofit retrofit = builder.build(); 

As you can see in the snippet above, the okhttp3.Response response = chain.proceed(request); line accesses the server response. Consequently, we can check the status code with if (response.code() == 500) and then open the ServerIsBrokenActivity.


I was able to accomplish that by adding an interceptor to the OkHttpClient that retrofit is using.

Kotlin + Retrofit 2.x

val clientBuilder = OkHttpClient.Builder()
clientBuilder.addInterceptor { chain ->
            val request = chain.request()
            val response = chain.proceed(request)
            if (response.code() == 403) {
                handleForbiddenResponse()
            }
            response
        }

Retrofit 2.x:

   OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
   clientBuilder.
            addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                   Request request = chain.request();
                   Response response = chain.proceed(request);
                   if (response.code() == 403) {
                         handleForbiddenResponse();
                   }
                   return response;
                }
            });


    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(clientBuilder.build();)
            .build();

Retrofit 1.x:

public class ForbiddenInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        if (response.code() == 403) {
             handleForbiddenResponse();
        }
        return response;
    }
}



OkHttpClient okHttpClient = Utils.createUnsafeOkHttpClient();
okHttpClient.interceptors().add(new ForbiddenInterceptor());

RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
        .setEndpoint(API_BASE_URL)
        .setClient(new OkClient(okHttpClient));

Another possibility is to override the execute method in Retrofit's OkClient. In my case I was looking for a specific response header, so it went something like this:

OkClient client = new OkClient(okHttpClient) {
    @Override
    public retrofit.client.Response execute(retrofit.client.Request request) throws IOException {
        retrofit.client.Response response = super.execute(request);

        // Do whatever with 'response', such as looking for the value of a particular header:

        List<retrofit.client.Header> headers = response.getHeaders();
        for (retrofit.client.Header header : headers) {
            if (MY_HEADER.equalsIgnoreCase(header.getName())) {
                this.savedValue = header.getValue();
                break;
            }
        }

        return response;
    }
};

RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
        .setEndpoint(API_BASE_URL)
        .setClient(client);