Retrofit / OkHttp3 400 Error Body Empty

吃可爱长大的小学妹 提交于 2021-02-08 13:32:04

问题


I am using Retrofit 2 in my Android project. When I hit an API endpoint using a GET method and it returns a 400 level error I can see the error content when I use an HttpLoggingInterceptor, but when I get to the Retrofit OnResponse callback the error body's string is empty.

I can see that there is a body to the error, but I can't seem to pull that body when in the context of the Retrofit callback. Is there a way to ensure the body is accessible there?

Thanks, Adam

Edit: The response I see from the server is: {"error":{"errorMessage":"For input string: \"000001280_713870281\"","httpStatus":400}}

I am trying to pull that response from the response via: BaseResponse baseResponse = GsonHelper.getObject(BaseResponse.class, response.errorBody().string()); if (baseResponse != null && !TextUtils.isEmpty(baseResponse.getErrorMessage())) error = baseResponse.getErrorMessage();

(GsonHelper is just a helper which passes the JSON string through GSON to pull the object of type BaseResponse)

The call to response.errorBody().string() results in an IOException: Content-Length and stream length disagree, but I see the content literally 2 lines above in Log Cat


回答1:


I encountered the same problem before and I fixed it by using the code response.errorBody().string() only once. You'll receive the IOException if you are using it many times so it is advised to just use it as a one-shot stream just as the Documentation on ResponseBody says.

My suggestion is: convert the Stringified errorBody() into an Object immediately as the latter is what you're gonna be using on subsequent operations.




回答2:


First create an Error class like below:

public class ApiError {
    @SerializedName("httpStatus")
    private int statusCode;
    @SerializedName("errorMessage")
    private String message;

    public ApiError() {

    }

    public ApiError(String message) {
        this.message = message;
    }

    public ApiError(int statusCode, String message) {
        this.statusCode = statusCode;
        this.message = message;
    }

    public int status() {
        return statusCode;
    }

    public String message() {
        return message;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }
}

Second you can create a Utils class to handle your error like below:

public final class ErrorUtils {
    private ErrorUtils() {

    }

    public static ApiError parseApiError(Response<?> response) {
        final Converter<ResponseBody, ApiError> converter =
                YourApiProvider.getInstance().getRetrofit()
                        .responseBodyConverter(ApiError.class, new Annotation[0]);

        ApiError error;
        try {
            error = converter.convert(response.errorBody());
        } catch (IOException e) {
            error = new ApiError(0, "Unknown error"
        }
        return error;
    }

And finally handle your error like below:

if (response.isSuccessful()) {
   // Your response is successfull
   callback.onSuccess();
   } 
else {
   callback.onFail(ErrorUtils.parseApiError(response));
   }

I hope this'll help you. Good luck.




回答3:


If you are gettig 400 then its a bad request you r trying to send to server. check your get req.



来源:https://stackoverflow.com/questions/38383401/retrofit-okhttp3-400-error-body-empty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!