rx java retrofit 2 error handling

后端 未结 3 1661
無奈伤痛
無奈伤痛 2020-12-31 23:36

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,

相关标签:
3条回答
  • 2021-01-01 00:11

    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();
    
    0 讨论(0)
  • 2021-01-01 00:12

    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);
    
    0 讨论(0)
  • 2021-01-01 00:28

    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 HttpExceptions 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.

    0 讨论(0)
提交回复
热议问题