Affects: Spring boot 3.2.4
Since upgrading to Spring boot 3.2.4 from 3.2.3 the Custom exception handler does not send response with the custom message in body.
Spring boot 3.2.3
MockHttpServletResponse:
Status = 500
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body = {"status":"INTERNAL_SERVER_ERROR","message":"An error occurred."}
Forwarded URL = null
Redirected URL = null
Cookies = []
Spring boot 3.2.4+
MockHttpServletResponse:
Status = 500
Error message = null
Headers = [Content-Type:"application/json"]
Content type = application/json
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
I have reproduced the issue in this sample project, DeferredDemo.zip. This issue persists in Spring Boot 3.3.0
Comment From: Meijuh
Related to the problem here, might be the work done in this issue: https://github.com/spring-projects/spring-framework/issues/32340.
Comment From: rstoyanchev
The sample doesn't seem to be working as described above. DemoController returns new DeferredResult()
. That results in AsyncRequestTimeoutException
, which is handled by DemoExceptionHandler
but it uses the exception message which is null. I changed it to ""An error occurred." but it works with both 3.2.4 and 3.2.3.
Comment From: bthers-dish
It is curious that it is working for you but fails on our systems. I have tested it with both Java 17 and 21.
I added AsyncRequestTimeoutException
exception handling to the DemoExceptionHandler
and added a test to throw the AsyncRequestTimeoutException
. I also set the message of the error response to the exception title.
Both tests are still failing with an Unparsable JSON string
message due to the response body being empty.
DeferredDemo.zip
Comment From: rstoyanchev
The tests are using AsyncListener#onError
which typically indicates a network or I/O error after the response is no longer usable. We now protect the response from being used in such cases because Servlet containers recycle the request and response and writing may affect the response for a different request.
If I switch the timeout test on AsyncListener#onTimeout
which is what is actually called in case of a timeout, the test passes.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.