package com.uber.retrofit2.adapters.network.exception; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import okhttp3.Request; import retrofit2.Call; import retrofit2.CallAdapter; import retrofit2.Callback; import retrofit2.Retrofit; /** * A {@linkplain CallAdapter.Factory call adapter} that wraps {@link IOException} with its {@link Request} * in {@link NetworkException}. * * NOTE: This is a forwarding adapter and delegates to another call adapter. It must be registered to your * {@link Retrofit} instance before the adapter it delegates to. */ public final class NetworkExceptionCallAdapterFactory extends CallAdapter.Factory { /** * @return an instance which will wrap any {@link IOException} with its corresponding {@link Request}. */ public static NetworkExceptionCallAdapterFactory create() { return new NetworkExceptionCallAdapterFactory(); } @Override public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { return new NetworkExceptionCallAdapter(retrofit.nextCallAdapter(this, returnType, annotations)); } /** * Wraps a delegate call adapter and passes on a {@link NetworkExceptionCall} which performs * {@link IOException} wrapping when an error is encountered upon invoking * {@link NetworkExceptionCall#enqueue(Callback)} or {@link NetworkExceptionCall#execute()}. */ private static final class NetworkExceptionCallAdapter implements CallAdapter { private final CallAdapter delegateCallAdapter; NetworkExceptionCallAdapter(CallAdapter delegateCallAdapter) { this.delegateCallAdapter = delegateCallAdapter; } @Override public Type responseType() { return delegateCallAdapter.responseType(); } @Override public Object adapt(Call call) { return delegateCallAdapter.adapt(new NetworkExceptionCall<>(call)); } } }