I\'m using retrofit 2 along with rx java
Situation: the app sends some request, then i get the response in json-format that is automatically converted to User dto,
I believe in the case you mentioned you will just enter into your onError
handling, because retrofit will fail to deserialize your response, as it's not formatted as a List
. You could potentially handle your case through that based off of the exception type.
If you can't alter the api to return consistent response types, you will have to look into using TypedInput, and possibly a converter.
Additionally, while it may not be completely relevant/overkill to the situation at hand, TypeAdapters bear mentioning. They'll let you determine how retrofit
deserializes gson
on a per class basis.
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyClass.class, new MyAdapter())
.create();
RestAdapter adapter = new RestAdapter.Builder()
.setConverter(new GsonConverter(gson))
.build();
I had the same situation and the way I could get the json from the server when an error occurs was something like this:
retrofit2.Response<TokenRefresh> r = call.execute();
String errorMessage = "";
try {
errorMessage = r.errorBody().string();
} catch (IOException e) {
e.printStackTrace();
}
Timber.d("errorMessage: " + errorMessage);
Depending on the server response you might or might not get into your onError
function. If the server returns a non-2XX http status code you'll get into the onError
method. If on the other hand you get a 2XX http status code you'll enter onNext
.
I'm assuming you can deal with the onNext
bit and I'll explain how you can do it in the onError
. It's important to realise that there are many ways of doing this and this is just an example that uses okhttp 3 and retrofit 2 beta4.
So retrofit2 says that every non-2XX http responses are HttpException
s when using rxjava
. This you already have it there in your code:
if (e instanceof retrofit.HttpException) {
HttpException exception = (HttpException) e;
}
Now what you want to do is get the body of the response. This you can achieve by calling Response response = exception.response()
in the HttpException
you have there. With the response, getting the error body is quite straight forward. You just call response.errorBody()
. You can then convert the body to a java object or just access it as a string.
Since you have a json
error body as an example, here's how you can convert the response body to a java object:
new GsonConverterFactory().responseBodyConverter(type,
new Annotation[0]).convert(response.errorBody());
where type
is the class of the java object that represents the error.
So putting it all together, on your onError
method you could write something like:
if (e instanceof retrofit.HttpException) {
HttpException exception = (HttpException) e;
Response response = exception.response();
Converter<ResponseBody, MyError> converter = new GsonConverterFactory()
.responseBodyConverter(MyError.class, Annotation[0]);
MyError error = converter.convert(response.errorBody());
}
MyError
is a model that represents the error json you have in your question.