Render global errors as Problem Details
Spring Boot handles errors globally as JSON responses or HTML pages. This is powered by ErrorController and ErrorAttributes.
Spring Framework added support for Problem Details and Spring Boot auto-configures this as of #32634.
This issue is about rendering global errors in the problem details format consistently, as well as providing a path forward to making this the default in the future. This means that ErrorAttributes would need to produce a ProblemDetail or ErrorResponse instead of a Map. Also, we would probably need to revisit the backing infrastructure to better align with Framework. There are upcoming changes in Framework that could help us to improve the support and make it more lightweight, see https://github.com/spring-projects/spring-framework/issues/34272.
Hi @bclozel , I would like to collaborate. Can I work on this issue?
@kiruthiga1793 Thanks for the proposal but the issue is already assigned and I have a good chunk of changes ready. We're waiting for changes in Framework to complete this work.
@bclozel Thanks for letting me know. Add me also next time if possible if the issue has some sub tasks.
Hi Brian,
in our company we implemented ErrorAttributes and ErrorView in a way that the Map structure resembled the JSON Problem structure for all spring framework exceptions and also added extension points for individual other exceptions. So I'm curious about the new improvement that come with Spring Framework and the way how exception handling will change in Spring Boot.
@danielrohe Is your application enabling problem details support in Spring Boot with the spring.mvc.problemdetails.enabled=true property? This should take care of handling most exceptions thrown by Spring Framework and render them as Problem Details responses in JSON or XML format with i18n support.
Currently, exceptions that are not handled at this point escape to the global Spring Boot error handling and are rendered as traditional Spring Boot errors. The goal of this issue if to make those problem details responses. Note, Spring Framework must first extend its error rendering support to render HTML error pages https://github.com/spring-projects/spring-framework/issues/34272.
Hopefully once this is all done, you won't have to maintain this custom error handling setup anymore as this will all be done for you.
Hi Brian,
no, we didn't use Spring Framework's ProblemDetails support We implemented this approach of overwriting ErrorAttributes and ErrorView before Spring Framework supported Problem Details. This solution worked out quite well for all Spring Framework exceptions and also others like javax-validation's ConstraintViolationException for services that serve JSON and web (HTML) traffic. In addition we also have a Problem Details implementation at https://github.com/zalando/problem-spring-web that served pure backend services just serving JSON. For these services we can replace it with Spring Framework's Problem Details support as the responses are mostly similar. For the services that serve JSON and HTML we are using our implementation because the current Spring Framework does not support serving web (HTML) traffic. Therefore I'm curious what this new implementation will bring and whether its possible for users to utilize it for other framework exceptions like javax-validation's ConstraintViolationException.
Hi Brian,
I did some more testing and a big difference between the current Error Response and the Error Attributes is that Error Responses does not include the binding results like FieldError. Is this also planned with the new feature?
@danielrohe I'm not sure I understand what you mean but this sounds like https://github.com/spring-projects/spring-framework/issues/34061
Hi Brian, yes similar to the mentioned issue. In case of validation errors I think the API should still respond with a presentation of binding errors (e.g. JSON pointer to attribute, code and message) to provide e.g. JS frontends the possibility to display the error message (e.g. either mapped from code or taken from message) at the input field (identified by the JSON pointer) that caused the error. Similar to how Binding Errors (e.g. FieldError) work with backend rendering frameworks like thymeleaf.
@danielrohe that's not something that we can change in Spring Boot. This would require a change or new configuration option in Spring Framework. Maybe you can comment on that other issue and explain the use case? Thanks!
Hi, maybe specific documentation should be added in the meantime to https://docs.spring.io/spring-boot/reference/web/servlet.html#web.servlet.spring-mvc.error-handling (and/or maybe roadmaps for when future version may allow to do this more easily) for this use case of "always render as problemdetail (e.g. with fields title/detail/instance)". For exemple when the user code throws IllegalArgumentException or RuntimeException (which currently render in json with the old json format error/message).
My current understanding is to use "spring.mvc.problemdetails.enabled=true" and also a controllerAdvice for a global exception handler
@ExceptionHandler(Throwable.class)
public ProblemDetail handleAny(Throwable ex, HttpServletRequest request) {
// create and return populated problem detail here
}
but there's quite a bit of freedom in the code to create the problem detail in the global exeception handler so some official guidance for this specific use case would add a lot of value I think
ps: I think you can also define an ErrorAttributes bean that provides a map with the same keys as the fields in problem detail but this looks like it's less composable than defining an exceptionhandler that returns a problemdetail. I'm not sure though.
@danielrohe Zalando Problem Spring web lib is good, I have used it in my real project for 3 years. Worked well as expected, but it is not aligned with the new Spring Boot 4. Especially, it is dependent on Jackson 2.
In these days I have tried to upgrade my projects to Spring Boot 4, when removing Zalando problem spring web from the project, it will lack some features:
- Jakarta Validation Exceptions handling
- Global errors in Problem Details format
- Translate the exceptions in Spring Security config as normal exceptions.
The first issue is easy to resolve by adding a custom exception handler.
For the second, it seems we have to override the Spring Boot built-in exception handler for it, or convert the ErrorResponse/ErrorResponseExceptoin.
For the 3rd, we have some path variable check in Spring Security Config, and used some custom exceptions, now either setup exceptionHandling{} block or using exception handlers, it did not work and always returns Spring Boot errors 500.
I will not simply try to migrate the Zalando Problem Spring library. But I'm happy to discard the existing code and focus on tighter integration with Spring Boot's existing classes.
For 1. I have something prepared that uses the same mechanism as Spring Boot's ResponseEntityExceptionHandler but does not need a Jackson Module For 2. Spring Boot's ResponseEntityExceptionHandler should do the magic For 3. I don't see a need and especially security related exceptions should not expose sensitive information
@kiruthiga1793 Thanks for the proposal but the issue is already assigned and I have a good chunk of changes ready. We're waiting for changes in Framework to complete this work.
@bclozel Could you tell me in which version you expect to officially support this feature? Or do you know whether it will be introduced in Spring Boot 4.x or Spring Boot 5.x?
@ximinghui right now it's assigned to the 4.x milestone and this reflects our intent.