Description
Affects: Spring framework 6
Expected behaviour:
A project that has a @ControllerAdvice
annotated class that extends ResponseEntityExceptionHandler
renders correct json of the exception it handles.
Actual behaviour: When an exception occurs during serialization (jackson) of a field in ((open) projection) interfaces, there is an invalid json being created. First the object get serialized up till where the exception occured, that object is closed and then the object of the rfc7807 is serialized afterwards.
Reproduce
This bug is easily reproducible with a very limited sample codebase: https://github.com/Jenson3210/bug-demo
- Run this codebase
- Call endpoint
localhost:8080/interface
and see returns 2 objects iso 1 error object{"type":"interface","interfaceField":"field"}
and{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"Failed to write request","instance":"/interface"}
This first object contains a type annotation derived from Jackson type annotation and a field which was succefully "calculated" - Call endpoint
localhost:8080/projection
and see it returns 2 objects instead of 1 error object{}
and{"type":"about:blank","title":"Internal Server Error","status":500,"detail":"Failed to write request","instance":"/projection"}
- Remove
extends ResponseEntityExceptionHandler
fromControllerExceptionHandler
class. (or simply switch the commented lines) - See the endpoints now return proper json.
Possible solutions
The proxy for projections could be caching and checking on instantiation if all fields are retrievable. If resource-expensive operations need to be calculated, by caching they do not need to be recalculated by Jackson again. This is of course only a solution for the projections.
Comment From: bclozel
I think this is a duplicate of #31104 (that we later refined in #31154). What's happening here is that the error happens after we've started writing to the response and the exception handling adds more content to the response, making the entire thing somewhat invalid.
We are now attempting to reset the response body if possible, before error handling writes to the response.
Can you test your application with Spring Boot 3.2.0-RC1 and let us know if the behavior is improved? Your sample application is 404 to me so I can't test it myself. Thanks!
Comment From: Jenson3210
@bclozel I made the demo repo public (sorry for that) I will try the RC1 and let you know. Seems like resetting should fix this indeed. I will get feedback on the RC
Comment From: Jenson3210
@bclozel RC-1 fixes this indeed! great to know it is coming. Can be closed! Did not find this issue as I searched for wrong params. Sorry for doubles!
Comment From: bclozel
Great news, and thanks for testing our release candidate! We can't really backport this change in 6.0.x, so applications will need to upgrade to Spring Boot 3.2 / Spring Framework 6.1 to get this behavior.