Forked from joen93/RxErrorHandlingCallAdapterFactory.java
Last active
September 7, 2017 17:30
-
-
Save rqbazan/b8f3af5ea4dde69c5ce94ddce28d7026 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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Reimplemented by RqBazan on 02/07/17. | |
* | |
* 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 RxJava2ErrorHandlingCallAdapterFactory extends CallAdapter.Factory { | |
private final RxJava2CallAdapterFactory mOriginalCallAdapterFactory; | |
private RxJava2ErrorHandlingCallAdapterFactory() { | |
mOriginalCallAdapterFactory = RxJava2CallAdapterFactory.create(); | |
} | |
public static CallAdapter.Factory create() { | |
return new RxJava2ErrorHandlingCallAdapterFactory(); | |
} | |
@SuppressWarnings("unchecked") | |
@Nullable | |
@Override | |
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { | |
return new RxCallAdapterWrapper(retrofit, mOriginalCallAdapterFactory.get(returnType, annotations, retrofit)); | |
} | |
private static class RxCallAdapterWrapper<R> implements CallAdapter<R, Object> { | |
private final Retrofit mRetrofit; | |
private final CallAdapter<R, Object> mWrappedCallAdapter; | |
public RxCallAdapterWrapper(final Retrofit retrofit, final CallAdapter<R, Object> wrapped) { | |
mRetrofit = retrofit; | |
mWrappedCallAdapter = wrapped; | |
} | |
@Override | |
public Type responseType() { | |
return mWrappedCallAdapter.responseType(); | |
} | |
@SuppressWarnings("unchecked") | |
@Override | |
public Object adapt(final Call<R> call) { | |
Object original = mWrappedCallAdapter.adapt(call); | |
if (original instanceof Observable) { | |
return ((Observable) original).onErrorResumeNext(new Function<Throwable, ObservableSource>() { | |
@Override | |
public ObservableSource apply(Throwable throwable) throws Exception { | |
return Observable.error(asRetrofitException(throwable)); | |
} | |
}); | |
} else if (original instanceof Flowable) { | |
return ((Flowable) original).onErrorResumeNext(new Function<Throwable, Publisher>() { | |
@Override | |
public Publisher apply(Throwable throwable) throws Exception { | |
return Flowable.error(asRetrofitException(throwable)); | |
} | |
}); | |
} else if (original instanceof Single) { | |
return ((Single) original).onErrorResumeNext(new Function<Throwable, SingleSource>() { | |
@Override | |
public SingleSource apply(Throwable throwable) throws Exception { | |
return Single.error(asRetrofitException(throwable)); | |
} | |
}); | |
} else if (original instanceof Maybe) { | |
return ((Maybe) original).onErrorResumeNext(new Function<Throwable, MaybeSource>() { | |
@Override | |
public MaybeSource apply(Throwable throwable) throws Exception { | |
return Maybe.error(asRetrofitException(throwable)); | |
} | |
}); | |
} else if (original instanceof Completable){ | |
//Completable then | |
return ((Completable) original).onErrorResumeNext(new Function<Throwable, CompletableSource>() { | |
@Override | |
public CompletableSource apply(Throwable throwable) throws Exception { | |
return Completable.error(asRetrofitException(throwable)); | |
} | |
}); | |
} else { | |
return original; | |
} | |
} | |
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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment