Created
June 6, 2016 05:39
-
-
Save vipulshah2010/2178a46bbed3d7bf9ce2334c02079a36 to your computer and use it in GitHub Desktop.
RxAndroid Error Handling
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
public class RetrofitException extends RuntimeException { | |
public static RetrofitException httpError(String url, Response response, Retrofit retrofit) { | |
String message = response.code() + " " + response.message(); | |
return new RetrofitException(message, url, response, Kind.HTTP, null, 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); | |
} | |
/** Identifies the event kind which triggered a {@link RetrofitException}. */ | |
public enum Kind { | |
/** An {@link IOException} occurred while communicating to the server. */ | |
NETWORK, | |
/** A non-200 HTTP status code was received from the server. */ | |
HTTP, | |
/** | |
* An internal error occurred while attempting to execute a request. It is best practice to | |
* re-throw this exception so your application crashes. | |
*/ | |
UNEXPECTED | |
} | |
private final String url; | |
private final Response response; | |
private final Kind kind; | |
private final Retrofit retrofit; | |
RetrofitException(String message, String url, Response response, Kind kind, Throwable exception, Retrofit retrofit) { | |
super(message, exception); | |
this.url = url; | |
this.response = response; | |
this.kind = kind; | |
this.retrofit = retrofit; | |
} | |
/** The request URL which produced the error. */ | |
public String getUrl() { | |
return url; | |
} | |
/** Response object containing status code, headers, body, etc. */ | |
public Response getResponse() { | |
return response; | |
} | |
/** The event kind which triggered this error. */ | |
public Kind getKind() { | |
return kind; | |
} | |
/** The Retrofit this request was executed on */ | |
public Retrofit getRetrofit() { | |
return retrofit; | |
} | |
/** | |
* HTTP response body converted to specified {@code type}. {@code null} if there is no | |
* response. | |
* | |
* @throws IOException if unable to convert the body to the specified {@code type}. | |
*/ | |
public <T> T getErrorBodyAs(Class<T> type) throws IOException { | |
if (response == null || response.errorBody() == null) { | |
return null; | |
} | |
Converter<ResponseBody, T> converter = retrofit.responseBodyConverter(type, new Annotation[0]); | |
return converter.convert(response.errorBody()); | |
} | |
} |
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
public class RxErrorHandlingCallAdapterFactory extends CallAdapter.Factory { | |
private final RxJavaCallAdapterFactory original; | |
private RxErrorHandlingCallAdapterFactory() { | |
original = RxJavaCallAdapterFactory.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<Observable<?>> { | |
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(); | |
} | |
@SuppressWarnings("unchecked") | |
@Override | |
public <R> Observable<?> adapt(Call<R> call) { | |
return ((Observable) wrapped.adapt(call)).onErrorResumeNext(new Func1<Throwable, Observable>() { | |
@Override | |
public Observable call(Throwable throwable) { | |
return Observable.error(asRetrofitException(throwable)); | |
} | |
}); | |
} | |
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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, thank you for this gist!
I use this gist in my project, when the web request returns connect refused by the server, a crash happened, have you ever met it?
Below is the crash log:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path at line 56,at line 21,at 37 at 34....