Skip to content

Instantly share code, notes, and snippets.

@benvium
Created August 29, 2014 19:45
Show Gist options
  • Star 67 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save benvium/66bf24e0de80d609dac0 to your computer and use it in GitHub Desktop.
Save benvium/66bf24e0de80d609dac0 to your computer and use it in GitHub Desktop.
Fairly simply Retrofit custom error handling example. Is set up so that you don't need to do much work in the 'failure' handler of a retrofit call to get the user-visible error message to show. Works on all endpoints. There's lots of exception handling as our server folks like to keep us on our toes by sending all kinds of random stuff..!
// on error the server sends JSON
/*
{ "error": { "data": { "message":"A thing went wrong" } } }
*/
// create model classes..
public class ErrorResponse {
Error error;
public static class Error {
Data data;
public static class Data {
String message;
}
}
}
//
/**
* Converts the complex error structure into a single string you can get with error.getLocalizedMessage() in Retrofit error handlers.
* Also deals with there being no network available
*
* Uses a few string IDs for user-visible error messages
*/
private static class CustomErrorHandler implements ErrorHandler {
private final Context ctx;
public CustomErrorHandler(Context ctx) {
this.ctx = ctx;
}
@Override
public Throwable handleError(RetrofitError cause) {
String errorDescription;
if (cause.isNetworkError()) {
errorDescription = ctx.getString(R.string.error_network);
} else {
if (cause.getResponse() == null) {
errorDescription = ctx.getString(R.string.error_no_response);
} else {
// Error message handling - return a simple error to Retrofit handlers..
try {
ErrorResponse errorResponse = (ErrorResponse) cause.getBodyAs(ErrorResponse.class);
errorDescription = errorResponse.error.data.message;
} catch (Exception ex) {
try {
errorDescription = ctx.getString(R.string.error_network_http_error, cause.getResponse().getStatus());
} catch (Exception ex2) {
Log.e(TAG, "handleError: " + ex2.getLocalizedMessage());
errorDescription = ctx.getString(R.string.error_unknown);
}
}
}
}
return new Exception(errorDescription);
}
}
// When creating the Server...
retrofit.RestAdapter restAdapter = new retrofit.RestAdapter.Builder()
.setEndpoint(apiUrl)
.setLogLevel(retrofit.RestAdapter.LogLevel.FULL)
.setErrorHandler(new CustomErrorHandler(ctx)) // use error handler..
.build();
server = restAdapter.create(Server.class);
// Now when calling server methods, get simple error out like this:
server.postSignIn(login, new Callback<HomePageResponse>() {
@Override
public void success(HomePageResponse homePageResponse, Response response) {
// Do success things!
}
@Override
public void failure(RetrofitError error) {
error.getLocalizedMessage(); // <-- this is the message to show to user.
}
});
@danielgomezrico
Copy link

Cool thanks for sharing

@philipgiuliani
Copy link

Wow thats handy :) Thanks a lot!

@mominbuet
Copy link

Is there anything for the synchronous(without the Callback) retrofit call?

@geekmario
Copy link

@mominbuet try{}catch(RetrofitError error){}

@bikeshtricon
Copy link

is there any way to get error stack trace in a string

@luongvo
Copy link

luongvo commented Feb 5, 2016

cool 👍

@jonathanvm13
Copy link

Thanks

@apidez
Copy link

apidez commented Aug 4, 2016

awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment