I found this.
But in new ver compile \'com.squareup.retrofit2:adapter-rxjava:2.2.0\'
at CallAdapter it has two params
CallAdapter,?>
Disclaimer: I'm the author of the blog post you referenced
The original post was meant as a proof of concept and for RxJava 2 so it's easier for me to explain with that version too, but I'll try and cover more ground. I'm guessing you're using version 1, since you talk about adapter-rxjava
and not adapter-rxjava2
. That said, the implementation for version 1 should be pretty straight forward and just a matter of using the right imports.
Here's what I've done using RxJava 2:
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 implements CallAdapter {
private final Retrofit retrofit;
private final CallAdapter wrapped;
public RxCallAdapterWrapper(Retrofit retrofit, CallAdapter wrapped) {
this.retrofit = retrofit;
this.wrapped = wrapped;
}
@Override
public Type responseType() {
return wrapped.responseType();
}
@Override
public Object adapt(Call call) {
Object result = wrapped.adapt(call);
if (result instanceof Single) {
return ((Single) result).onErrorResumeNext(new Function() {
@Override
public SingleSource apply(@NonNull Throwable throwable) throws Exception {
return Single.error(asRetrofitException(throwable));
}
});
}
if (result instanceof Observable) {
return ((Observable) result).onErrorResumeNext(new Function() {
@Override
public ObservableSource apply(@NonNull Throwable throwable) throws Exception {
return Observable.error(asRetrofitException(throwable));
}
});
}
if (result instanceof Completable) {
return ((Completable) result).onErrorResumeNext(new Function() {
@Override
public CompletableSource apply(@NonNull Throwable throwable) throws Exception {
return Completable.error(asRetrofitException(throwable));
}
});
}
return result;
}
private RetrofitException asRetrofitException(Throwable throwable) {
// We had non-200 http error
if (throwable instanceof HttpException) {
HttpException httpException = (HttpException) throwable;
Response response = httpException.response();
return RetrofitException.httpError(response.raw().request().url().toString(), response, retrofit);
}
// 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);
}
}
}
No major changes, just some playing around with return types. Now if you look at the RxJava2CallAdapter
it implements CallAdapter
, so we need to account for this.
Then I've added some checks for the instance types to make sure we're returning the right things.
The really important part is to make sure you import the right packages. Retrofit adapters check for specific classes. One problem I had was having the wrong imports and had situations where I was checking if the Throwable
was an instance of com.jakewharton.retrofit2.adapter.HttpException
, while it was actually an instance of retrofit2.adapter.rxjava2.HttpException
.
Hope this helps