Skip to content

Instantly share code, notes, and snippets.

@Anrimian
Last active November 5, 2017 16:25
Show Gist options
  • Save Anrimian/6c284900e0babfd1b62803b8477cd21a to your computer and use it in GitHub Desktop.
Save Anrimian/6c284900e0babfd1b62803b8477cd21a to your computer and use it in GitHub Desktop.
RetrofitRxJava2ErrorAdapter

Retrofit error processing util

Simple parsing errors with retrofit

Example

        CallAdapter.Factory callAdapterFactory = new RxJava2ErrorAdapterFactory(new DefaultErrorConverter(),
                RxJava2CallAdapterFactory.createWithScheduler(scheduler));//your scheduler here

        return new Retrofit.Builder()
                .baseUrl(baseUrl)//your api url
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(callAdapterFactory)
                .build();
public class DefaultErrorConverter implements ErrorConverter {
@NonNull
@Override
public Exception processServerError(HttpException httpException) {
ResponseBody body = httpException.response().errorBody();
Gson gson = new Gson();
TypeAdapter adapter = gson.getAdapter(ErrorResponse.class);//your error response class
try {
ErrorResponse errorResponse = (ErrorResponse) adapter.fromJson(body.string());
return new RemoteServerException(errorResponse);
} catch (Exception e) {
return e;
}
}
}
public interface ErrorConverter {
@NonNull
Exception processServerError(HttpException httpException);
}
public class RemoteServerException extends RuntimeException {
private ErrorResponse errorResponse;
public RemoteServerException(ErrorResponse errorResponse) {
this.errorResponse = errorResponse;
}
public ErrorResponse getErrorResponse() {
return errorResponse;
}
}
public class RxJava2ErrorAdapter<R> implements CallAdapter<R, Object> {
private ErrorConverter errorConverter;
private CallAdapter<R, Object> wrapped;
public RxJava2ErrorAdapter(ErrorConverter errorConverter, CallAdapter<R, Object> wrapped) {
this.errorConverter = errorConverter;
this.wrapped = wrapped;
}
@Override
public Type responseType() {
return wrapped.responseType();
}
@Override
public Object adapt(Call<R> call) {
Object result = wrapped.adapt(call);
if (result instanceof Observable) {
return ((Observable) result).onErrorResumeNext(new Function<Throwable, ObservableSource>() {
@Override
public ObservableSource apply(@NonNull Throwable throwable) throws Exception {
return Observable.error(tryConvertException(throwable));
}});
}
if (result instanceof Single) {
return ((Single) result).onErrorResumeNext(new Function<Throwable, SingleSource>() {
@Override
public SingleSource apply(@NonNull Throwable throwable) throws Exception {
return Single.error(tryConvertException(throwable));
}
});
}
if (result instanceof Maybe) {
return ((Maybe) result).onErrorResumeNext(new Function<Throwable, MaybeSource>() {
@Override
public MaybeSource apply(@NonNull Throwable throwable) throws Exception {
return Maybe.error(tryConvertException(throwable));
}
});
}
if (result instanceof Flowable) {
return ((Flowable) result).onErrorResumeNext(new Function<Throwable, Publisher>() {
@Override
public Publisher apply(@NonNull Throwable throwable) throws Exception {
return Flowable.error(tryConvertException(throwable));
}
});
}
if (result instanceof Completable) {
return ((Completable) result).onErrorResumeNext(new Function<Throwable, CompletableSource>() {
@Override
public CompletableSource apply(@NonNull Throwable throwable) throws Exception {
return Completable.error(tryConvertException(throwable));
}
});
}
throw new IllegalStateException("call is not instance of observable, but: " + result.getClass().getName());
}
@NonNull
private Throwable tryConvertException(Throwable throwable) {
if (throwable instanceof HttpException && errorConverter != null) {
return errorConverter.processServerError((HttpException) throwable);
}
return throwable;
}
}
public class RxJava2ErrorAdapterFactory extends CallAdapter.Factory {
private ErrorConverter errorConverter;
private RxJava2CallAdapterFactory rxJava2CallAdapterFactory;
public RxJava2ErrorAdapterFactory(ErrorConverter errorConverter, RxJava2CallAdapterFactory rxJava2CallAdapterFactory) {
this.errorConverter = errorConverter;
this.rxJava2CallAdapterFactory = rxJava2CallAdapterFactory;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new RxJava2ErrorAdapter(errorConverter, rxJava2CallAdapterFactory.get(returnType, annotations, retrofit));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment