Skip to content

Instantly share code, notes, and snippets.

@ziglee
Last active May 23, 2017 01:34
Show Gist options
  • Save ziglee/e6193b98ebca333b9d8f721ca7767130 to your computer and use it in GitHub Desktop.
Save ziglee/e6193b98ebca333b9d8f721ca7767130 to your computer and use it in GitHub Desktop.
import android.text.TextUtils;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import javax.net.ssl.HttpsURLConnection;
import br.com.experience.hsm.data.entity.ErrorEntity;
import br.com.experience.hsm.data.entity.ErrorResponse;
import io.reactivex.Flowable;
import io.reactivex.functions.Function;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Converter;
import retrofit2.HttpException;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
public class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
private final RxJava2CallAdapterFactory original;
private RxErrorHandlingCallAdapterFactory() {
original = RxJava2CallAdapterFactory.create();
}
public static CallAdapter.Factory create() {
return new RxErrorHandlingCallAdapterFactory();
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxCallAdapterWrapper<>(retrofit, original.get(returnType, annotations, retrofit));
}
private static class RxCallAdapterWrapper<R> implements CallAdapter<R, Flowable<R>> {
private final Retrofit retrofit;
private final CallAdapter<R, ?> wrapped;
RxCallAdapterWrapper(Retrofit retrofit, final CallAdapter<R, ?> wrapped) {
this.retrofit = retrofit;
this.wrapped = wrapped;
}
@Override
public Type responseType() {
return wrapped.responseType();
}
@SuppressWarnings("unchecked")
@Override
public Flowable<R> adapt(Call<R> call) {
return ((Flowable) wrapped.adapt(call)).onErrorResumeNext(new Function<Throwable, Flowable>() {
@Override
public Flowable apply(final Throwable throwable) {
return Flowable.error(asRetrofitException(retrofit, throwable));
}
});
}
}
private static RetrofitException asRetrofitException(Retrofit retrofit, Throwable throwable) {
if (throwable instanceof HttpException) {
return parseHttpException(retrofit, (HttpException) throwable);
}
if (throwable instanceof SocketTimeoutException) {
return RetrofitException.timeoutError((SocketTimeoutException) throwable);
}
if (throwable instanceof IOException) {
return RetrofitException.networkError((IOException) throwable);
}
if (throwable instanceof RetrofitException) {
return (RetrofitException) throwable;
}
return RetrofitException.unexpectedError(throwable);
}
private static RetrofitException parseHttpException(Retrofit retrofit, HttpException httpException) {
try {
Response response = httpException.response();
Converter<ResponseBody, ErrorEntity> converter = retrofit.responseBodyConverter(ErrorEntity.class, new Annotation[0]);
ErrorEntity errorEntity = converter.convert(response.errorBody());
String message = errorEntity.getMessage();
if (HttpsURLConnection.HTTP_UNAUTHORIZED == httpException.code()) {
return RetrofitException.sessionExpiredError(ErrorResponse.create().withError(message));
}
return RetrofitException.apiError(ErrorResponse.create().withError(message));
} catch (Exception ex) {
return RetrofitException.unexpectedError(ex);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment