Skip to content

Instantly share code, notes, and snippets.

@leeyc09
Created April 29, 2017 05:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leeyc09/d89c1f97e5449e21d4d1c5c4a457d405 to your computer and use it in GitHub Desktop.
Save leeyc09/d89c1f97e5449e21d4d1c5c4a457d405 to your computer and use it in GitHub Desktop.
RxErrorHandlingCallAdapterFactory
package net.stylemilk.app.repository.api.exception;
import java.io.IOException;
import java.lang.annotation.Annotation;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Response;
import retrofit2.Retrofit;
public class RetrofitException extends RuntimeException {
private final String mUrl;
private final Response mResponse;
private final Kind mKind;
private final Retrofit mRetrofit;
RetrofitException(String message, String url, Response response, Kind kind, Throwable exception, Retrofit retrofit) {
super(message, exception);
mUrl = url;
mResponse = response;
mKind = kind;
mRetrofit = retrofit;
}
public static RetrofitException httpError(String url, Response response, Throwable throwable, Retrofit retrofit) {
String message = response.code() + " " + response.message();
return new RetrofitException(message, url, response, Kind.HTTP, throwable, retrofit);
}
public static RetrofitException unauthorizedError(String url, Response response, Throwable throwable, Retrofit retrofit) {
String message = response.code() + " " + response.message();
return new RetrofitException(message, url, response, Kind.UNAUTHORIZED, throwable, retrofit);
}
public static RetrofitException networkError(IOException exception) {
return new RetrofitException(exception.getMessage(), null, null, Kind.NETWORK, exception, null);
}
public static RetrofitException unexpectedError(Throwable exception) {
return new RetrofitException(exception.getMessage(), null, null, Kind.UNEXPECTED, exception, null);
}
public static RetrofitException loginSessionRequestError(Throwable exception) {
return new RetrofitException(exception.getMessage(), null, null, Kind.LOGINSESSION, exception, null);
}
public String getUrl() {
return mUrl;
}
public Response getResponse() {
return mResponse;
}
public Kind getKind() {
return mKind;
}
public Retrofit getRetrofit() {
return mRetrofit;
}
public <T> T getErrorBodyAs(Class<T> type) throws IOException {
if (mResponse == null || mResponse.errorBody() == null) {
return null;
}
Converter<ResponseBody, T> converter = mRetrofit.responseBodyConverter(type, new Annotation[0]);
return converter.convert(mResponse.errorBody());
}
public enum Kind {
NETWORK,
HTTP,
UNAUTHORIZED,
UNEXPECTED,
LOGINSESSION
}
}
package net.stylemilk.app.repository.api;
import net.stylemilk.app.repository.api.exception.RetrofitException;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.HttpException;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import rx.Observable;
import rx.functions.Func1;
public class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
private final RxJavaCallAdapterFactory mOriginal;
private RxErrorHandlingCallAdapterFactory() {
mOriginal = RxJavaCallAdapterFactory.create();
}
public static CallAdapter.Factory create() {
return new RxErrorHandlingCallAdapterFactory();
}
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxCallAdapterWrapper(retrofit, mOriginal.get(returnType, annotations, retrofit));
}
private static class RxCallAdapterWrapper implements CallAdapter<Observable<?>> {
private final Retrofit mRetrofit;
private final CallAdapter<?> mWrapped;
public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter<?> wrapped) {
mRetrofit = retrofit;
mWrapped = wrapped;
}
@Override
public Type responseType() {
return mWrapped.responseType();
}
@Override
public <R> Observable<?> adapt(Call<R> call) {
return ((Observable) mWrapped.adapt(call))
.onErrorResumeNext(new Func1<Throwable, Observable>() {
@Override
public Observable call(Throwable throwable) {
return Observable.error(asRetrofitException(throwable));
}
});
}
private RetrofitException asRetrofitException(Throwable throwable) {
if (throwable instanceof HttpException) {
Response response = ((HttpException) throwable).response();
return RetrofitException.httpError(response.raw().request().url().toString(), response, throwable, mRetrofit);
}
if (throwable instanceof IOException) {
return RetrofitException.networkError((IOException) throwable);
}
return RetrofitException.unexpectedError(throwable);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment