1

I'm using retrofit 2.0.2 and okhttp3 to build my app. My server set http status code to 418 if server code has any logic error. like password doesn't match. response data is {"statuscode":500}. 500 means password doesn't match. I don't know how to read response data when okhttp3 get non-200 http status code. retrofit throw an exception when it gets 418.

My question is how to read Response Data even if http status code is not 200.

Any suggestion?

user3034559
  • 1,259
  • 2
  • 15
  • 31
  • I can get the response data by using: Interceptor networkInterceptor = new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request);String str = response.body().string();if(str == null){}int statusCode = response.code();if(statusCode > 418){}return response;}}; okBuilder.addNetworkInterceptor(networkInterceptor); My question has changed to how can I notify my listener in onError() method, because there is only one parameter in onError(Throwable e) method. – user3034559 Jul 05 '16 at 18:34
  • check out this answer http://stackoverflow.com/questions/35987037/how-to-handle-network-errors-in-retrofit-2-with-rxjava/35993268#35993268 – LordRaydenMK Jul 05 '16 at 18:44
  • Thanks LordRaydenMK, it's a good workaround. – user3034559 Jul 05 '16 at 20:29

1 Answers1

2

I assume you are defining your call as:

Observable<YourModel> doStuff();

You get a onSuccess callback for HTTP codes 200-300 and onError for HTTP error codes, network errors, parsing errors...

You can also define your call as:

Observable<Response<YourModel>> doStuff();

and you will get a call to onSuccess when there is a HTTP error.

In onSuccess you need to check response.isSuccess(). It returns true for 200-300 status codes and you can access the response body with response.body()

If response.isSuccess() returns false you can convert the error body to your model class using:

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());
}
LordRaydenMK
  • 13,074
  • 5
  • 50
  • 56
  • Where do you get the retrofit instance from? I'm using RxJava + Retrofit to consume the Rest and the onError callback only returns a Throwable – funkycookie Oct 14 '16 at 12:29
  • @PopAlex-Cristian `retrofit` is the Retrofit instance used to create your service. I usually inject it using Dagger. How are you going to pass it around is up to you. – LordRaydenMK Oct 14 '16 at 12:33
  • Is there a way to pass the custom error class instead of the Throwable in every callback instead of manually writing this? – funkycookie Oct 14 '16 at 12:36
  • @PopAlex-Cristian take a look at: https://gist.github.com/koesie10/bc6c62520401cc7c858f – LordRaydenMK Oct 14 '16 at 12:40
  • This looks rather complicated. Isn't there any other way? The OkHttp Body logging shows me the json error response from the server. – funkycookie Oct 14 '16 at 12:49
  • @PopAlex-Cristian I think you should ask a new question explaining in more details what you need done and what have you done so far. – LordRaydenMK Oct 14 '16 at 12:53
  • http://stackoverflow.com/questions/40043884/get-error-response-json-from-rest-server-instead-of-throwable – funkycookie Oct 14 '16 at 13:09