Alpha
Alpha

Reputation: 1914

Retrofit2 204 No Content has content exception

I get from server empty json ("{}") as a delete response with code 204.

In okhttp3.internal.http.HttpEngine class there is this annoying thing that gets thrown:

  if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
    throw new ProtocolException(
        "HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
  }

If you try return something without content (server side) in headers still Content-Length greater than 0;

Any non server side ideas how to solve this issue?

Upvotes: 1

Views: 4684

Answers (2)

breakline
breakline

Reputation: 6093

This can be avoided if used differently a bit. Instead of:

@DELETE("vehicles/{id}/")
Observable<Response<BaseResponse>> deleteVehicle(@Header("Authorization") String token, @Path("id") Long vehicleId);

I use:

@HTTP(method = "DELETE", path = "vehicles/{id}/", hasBody = true)
Observable<Response<BaseResponse>> deleteVehicle(@Header("Authorization") String token, @Path("id") Long vehicleId);

Upvotes: 3

iagreen
iagreen

Reputation: 32026

You can trap the ProtocolException in an interceptor and return a placeholder 204 Response. Caveats with this approach -- 1) you may end up trapping other protocol errors (too many redirects, etc). If this is a concern, you could compare e.getMessage() to okhttp's exception message and rethrow the exception if there is not a match. 2) you still don't have access to the original response, so if you are out of luck if you need to inspect any of the returned headers.

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addNetworkInterceptor(new Interceptor() {
  @Override
  public Response intercept(Chain chain) throws IOException {
      Response response;
      try {
        response = chain.proceed(chain.request());
      } catch (ProtocolException e) {
        response = new Response.Builder()
            .request(chain.request())
            .code(204)
            .protocol(Protocol.HTTP_1_1)
            .build();
      }
    return response;
  }
});

Upvotes: 5

Related Questions