eclipse-ee4j / eclipse-ee4j/jersey

Error responsebody truncated when RESPONSE_SET_STATUS_OVER_SEND_ERROR is set

Open
#5,279 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

It seems that #5035 introduced some unexpected behaviour. Specifically when the `ResponseWriter` processes unhandled errors and [completes](https://github.com/eclipse-ee4j/jersey/blob/d64cfaf0693afdd91b91bc3176daf7619abd1831/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java#L236) the `CompletableFuture responseContext` exceptionally. This causes an exception in the `writeResponseStatusAndHeaders` method of the `ResponseWriter` when response is processed with the `DefaultExceptionMapper`.
```java
115 @Override
116 public OutputStream writeResponseStatusAndHeaders(final long contentLength, final ContainerResponse responseContext)
117 throws ContainerException {
118 this.responseContext.complete(responseContext);
119
120 // first set the content length, so that if headers have an explicit value, it takes precedence over this one
121 if (responseContext.hasEntity() && contentLength != -1 && contentLength < Integer.MAX_VALUE) {
122 response.setContentLength((int) contentLength);
123 }
124 // Note that the writing of headers MUST be performed before
125 // the invocation of sendError as on some Servlet implementations
126 // modification of the response headers will have no effect
127 // after the invocation of sendError.
128 final MultivaluedMap headers = getResponseContext().getStringHeaders();
...
```
On line 118 the `responseContext` is completed again with the provided `ContainerResponse`. The `getResponseContext()` method, on line 128, calls `get()` on the `CompletableFuture` which results in a `ExecutionException` which is subsequently wrapped in a `ContainerException`. This leaves the response in a weird state since the `Content-Length` header is set on line 122. Ultimately this results in a truncated error message limited to 141 bytes (which is the length of the `DefaultExceptionMapper` default message: _"An exception mapping did not successfully produce and processed a response. Logging the exception propagated to the default exception mapper."_). This only happens when RESPONSE_SET_STATUS_OVER_SEND_ERROR is set to true.

I've created a [sample project](https://github.com/peter-janssen/reproducers/tree/eclipse-ee4j/jersey%235279) to demonstrate the issue. When using `JerseyTest` this issue does not occur in the `GrizzlyHttpContainer`.

P.S. I'd like to challenge the response entity of the `DefaultExceptionMapper`. The specification only calls for the status code to be set. Shouldn't the response remain empty?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.