eclipse-ee4j / eclipse-ee4j/jersey
Error responsebody truncated when RESPONSE_SET_STATUS_OVER_SEND_ERROR is set
- 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
Assessment
This issue has not been assessed yet.