I am using the Retrofit library to do REST calls to a service I am using.
If I make an API call to my service and have a failure, the service returns a bit of JSON
Using this you can get the error body
if (response != null && response.errorBody() != null) {
JSONObject jsonObject = new JSONObject(response.errorBody().string());
String error = jsonObject.getString("error");
}
Try this code
@Override
public void failure(RetrofitError error) {
String json = new String(((TypedByteArray)error.getResponse().getBody()).getBytes());
Log.v("failure", json.toString());
}
with Retrofit 2.0
@Override
public void onFailure(Call<Example> call, Throwable t) {
String message = t.getMessage();
Log.d("failure", message);
}
I was having the same. My problem was a long
field that was coming from server as an empty String
""
. Retrofit was giving NumberFormatException
because it seems like Gson doesn't convert an empty string to long
(I'd suggest to make it 0L or something). So I had to change:
long errorCode;
to
String errorCode;
As it was said before, I had no access to the JSON message when debugging. I finally found the error using RequestMaker page, maybe it helps someone else
http://requestmaker.com/
getBodyAs
to get a JSON Object.JsonObject responseAsJson = (JsonObject) retrofitError.getBodyAs(JsonElement.class);
String message = responseAsJson.get("error").getAsString(); //=> "Username already in use"
Confirmed working in Retrofit 1.x. Not sure what changes are required for Retrofit 2.x.
You can use the getBodyAs method of the RetrofitError
object. It converts the response to a Java object similarly to other Retrofit conversions. First define a class that describes your JSON error response:
class RestError {
@SerializedName("code")
public int code;
@SerializedName("error")
public String errorDetails;
}
Then use the previously mentioned method to get the object that describes the error in more detail.
catch(RetrofitError error) {
if (error.getResponse() != null) {
RestError body = (RestError) error.getBodyAs(RestError.class);
log(body.errorDetails);
switch (body.code) {
case 101:
...
case 102:
...
}
}
}
Retrofit 2.0 changed the way error responses are converter. You will need to get the right converter with the responseBodyConverter method and use it to convert the error body of the response. Barring exception handling this would be:
Converter<ResponseBody, RestError> converter
= retrofit.responseBodyConverter(RestError.class, new Annotation[0]);
RestError errorResponse = converter.convert(response.errorBody());
@LukaCiko answer not working now for me in retrofit 1.6.1. Here like I'm doing it now:
@Override
public void failure(RetrofitError retrofitError) {
String json = new String(((TypedByteArray)retrofitError.getResponse().getBody()).getBytes());
//own logic for example
ExampleHandlerError error = new Gson().fromJson(json, ExampleHandlerError.class);
}