2

I am using Retrofit2 with RxJava. So my call looks something like

subscriptions.add(authenticateUser(mReq, refreshRequest)
                .observeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .subscribe(authResponseModel -> {
                    processResponse(authResponseModel, userName, encryptedPass);
                }, throwable ->
                {
                    LOGW(TAG, throwable.getMessage());
                }));

It's an authentication api. So when the api call fails, I get a response from the server like

{"messages":["Invalid username or password "]}

along with 400 Bad Request

I get 400 Bad Request in the throwable object as expected. But I want to receive the message thrown by the server. I am unable to figure out how to go about doing it. Can someone help out.

iZBasit
  • 1,314
  • 1
  • 15
  • 30
  • does [this](http://stackoverflow.com/questions/33983022/handle-errors-in-retrofit-2-rx) help – Blackbelt Mar 14 '16 at 12:04
  • Nope. The throwable just gives 400 bad request. – iZBasit Mar 14 '16 at 12:08
  • 2
    did you check `((HttpException) e).response().errorBody()` ? – Blackbelt Mar 14 '16 at 12:09
  • Even what you have suggested gives `Response{protocol=http/1.1, code=400, message=Bad Request, url=****/authenticate}` – iZBasit Mar 14 '16 at 12:24
  • 3
    `((HttpException) e).response()` returns the response object. There you have the real body of the response, `response.body()` - usually for http 200 - and the error body which should be filled in case of error. Check the content of both. – Blackbelt Mar 14 '16 at 12:28
  • 2
    Take a look at [this example](https://github.com/square/retrofit/blob/master/samples/src/main/java/com/example/retrofit/DeserializeErrorBody.java) in Retrofit's codebase. It makes use of a `Converter` which maps the error body to a java object. – Egor Neliuba Mar 14 '16 at 14:02

1 Answers1

4
if(throwable instanceof HttpException) {
    //we have a HTTP exception (HTTP status code is not 200-300)
    Converter<ResponseBody, Error> errorConverter =
        retrofit.responseBodyConverter(Error.class, new Annotation[0]);
    //maybe check if ((HttpException) throwable).code() == 400 ??
    Error error = errorConverter.convert(((HttpException) throwable).response().errorBody());
}

Assuming you are using Gson:

public class Error {
    public List<String> messages;
}

the content of messages should be a list of error messages. In your example messages.get(0) would be: Invalid username or password

LordRaydenMK
  • 13,074
  • 5
  • 50
  • 56