Skip to content

Instantly share code, notes, and snippets.

@joen93
Created April 5, 2017 12:56
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save joen93/7d4ae30ce29bef6127d74a26de151985 to your computer and use it in GitHub Desktop.
Save joen93/7d4ae30ce29bef6127d74a26de151985 to your computer and use it in GitHub Desktop.
RxJava2 and Retrofit 2.2.0 compatible factory, which wraps the {@link RxJava2CallAdapterFactory} and takes care of the error conversion.
/**
* RxJava2 and Retrofit 2.2.0 compatible factory,
* which wraps the {@link RxJava2CallAdapterFactory} and takes care of the error conversion.
*
* Based on: https://github.com/square/retrofit/issues/1102#issuecomment-241250796
*/
public class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
private final RxJava2CallAdapterFactory mOriginalCallAdapterFactory;
private RxErrorHandlingCallAdapterFactory() {
mOriginalCallAdapterFactory = RxJava2CallAdapterFactory.create();
}
public static CallAdapter.Factory create() {
return new RxErrorHandlingCallAdapterFactory();
}
@Override
public CallAdapter<?, ?> get(final Type returnType, final Annotation[] annotations, final Retrofit retrofit) {
return new RxCallAdapterWrapper<>(retrofit, mOriginalCallAdapterFactory.get(returnType, annotations, retrofit));
}
private static class RxCallAdapterWrapper<R> implements CallAdapter<R, Observable<R>> {
private final Retrofit mRetrofit;
private final CallAdapter<R, ?> mWrappedCallAdapter;
public RxCallAdapterWrapper(final Retrofit retrofit, final CallAdapter<R, ?> wrapped) {
mRetrofit = retrofit;
mWrappedCallAdapter = wrapped;
}
@Override
public Type responseType() {
return mWrappedCallAdapter.responseType();
}
@SuppressWarnings("unchecked")
@Override
public Observable<R> adapt(final Call<R> call) {
return ((Observable) mWrappedCallAdapter.adapt(call)).onErrorResumeNext(new Function<Throwable, ObservableSource>() {
@Override
public Observable apply(final Throwable throwable) {
return Observable.error(asRetrofitException(throwable));
}
});
}
private RetrofitException asRetrofitException(final Throwable throwable) {
// We had non-200 http error
if (throwable instanceof HttpException) {
final HttpException httpException = (HttpException) throwable;
final Response response = httpException.response();
return RetrofitException.httpError(response.raw().request().url().toString(), response, mRetrofit);
}
// A network error happened
if (throwable instanceof IOException) {
return RetrofitException.networkError((IOException) throwable);
}
// We don't know what happened. We need to simply convert to an unknown error
return RetrofitException.unexpectedError(throwable);
}
}
}
@marvinmosa
Copy link

this is not working if I am using Completable getData(...) instead of ObservablegetData(...). Hope you could help us.

@challme28
Copy link

challme28 commented May 23, 2017

What is RetrofitException? Could you give an example if its something I should implement?

@zkvarz
Copy link

zkvarz commented Mar 14, 2018

Did anyone had this Exception?
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.reflect.Type retrofit2.CallAdapter.responseType()' on a null object reference
line 34.

Any ideas why mWrappedCallAdapter might be null?

@arnoid
Copy link

arnoid commented Aug 16, 2018

@zkvarz

I have same issue now. Trying to find solution.

Have you solved that issue?

@alexxgarci
Copy link

Same here! @zkvarz @arnoid

Have you solved that issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment