I have a custom error handler that checks RetrofitError
it gets passed and rethrows it as custom exceptions
private static ErrorHandler getErrorHandler() {
return new ErrorHandler() {
@Override
public Throwable handleError(RetrofitError cause) {
switch (cause.getKind()) {
case NETWORK: return new NetworkException(cause);
case HTTP: return new ApiException(cause);
default: return cause;
}
}
};
}
If this is my endpoint
@GET(USERS_GET_URL)
User getUsers() throws NetworkException, ApiException;
while executing synchronous request I try...catch
and handle each custom exception as I want. When it is done asynchronously using
@GET(USERS_GET_URL)
void getUsers(Callback<User> cb) throws NetworkException, ApiException;
the handled exception gets rethrown as RetrofitError
. The following snippet of code is from CallbackRunnable
class of Retrofit
which executes the request
try {
final ResponseWrapper wrapper = obtainResponse();
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.success((T) wrapper.responseBody, wrapper.response);
}
});
} catch (RetrofitError e) {
Throwable cause = errorHandler.handleError(e);
final RetrofitError handled = cause == e ? e : unexpectedError(e.getUrl(), cause);
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.failure(handled);
}
});
}
As it can be seen, my custom exceptions are getting rethrown as RetrofitError
which makes me loose valuable information. Is there any way I can bypass custom error handling for just the async requests?
In your
ErrorHandler
you pathing originalRetrofitError
as cause, so as result in yourCallback#failure(RetrofitError error)
to get actual information you need to write next code:error.getCause().getCause()
. This error will contain response that server send with all the data.But error handler was created for sync request and after some time square team decided to close this gap this way. For more info you can read: https://gist.github.com/benvium/66bf24e0de80d609dac0
As for me, I don't recommend to use
ErrorHander
for async way, because I don't find any good solution to handle different types of error. It was much easier to get data right from initialRetrofitError
.