Affects: 6.0.3


After migrating to Boot 3 in my Boot application that has a @ControllerAdvice extending ResponseEntityExceptionHandler, my application started retrieving Errors using the ProblemDetail spec, overriding Boot's Error Handling mechanism.

All good up to that point, but my input validations are not retrieving the validation messages anywhere.

For example, I might have this constraint in my DTO:

@NotNull(message = "a custom validation error")
Long foo,

But the response for a request sending a null value for this field looks as follows:

{
    "type": "about:blank",
    "title": "Bad Request",
    "status": 400,
    "detail": "Invalid request content.",
    "instance": "/bar"
}

Shouldn't the detail contain the validation message, or, since there can be a number of binding errors, be included as an ProblemDetail.properties entry, resulting in an extra response body field?

Comment From: bclozel

I'm not sure how we should handle this at the Framework level. In Spring Boot error handling support, this is configurable through a property and is disabled by default because this leaks implementation details and can be considered a security issue.

Comment From: rozagerardo

Thanks for the response @bclozel

I haven't analyzed this in detail, but couldn't we consistently make all the ResponseEntityExceptionHandler.handleXXX methods call the createProblemDetail method, instead of just the "Lower level exceptions, and exceptions used symmetrically on client and server" ones?

Note: We can simply make createProblemDetail retrieve the ProblemDetail right away by default if we see it is an ErrorResponse exception with a ProblemDetail body, instead of (or in addition) doing that inside the handleExceptionInternal method as we're currently doing.

With this, the user can override the createProblemDetail method, having access to the actual exception, and include the binding errors only if they want to.

Otherwise, in the createResponseEntity method we can customize the response that is finally retrieved, but at this stage we don't have access to the original exception to use it accordingly.

Let me know if this makes sense, or if I should clarify the suggested solution using code snippets.

Comment From: rstoyanchev

As Brian mentioned, we don't include such details by default because it exposes implementation details. However, there are a couple of ways to customize this.

The easiest one is to use the ResourceBundle support, and add a problemDetail.title.MethodArgumentNotValidException property. You'll see in the documentation that we expose the list of global errors at {0} and the list of field errors at {1}.

If you want more control, you can override the appropriate exception handling method. Note that you don't need createProblemDetail, because all exceptions in spring-web and spring-webmvc implement ErrorResponse, and already contain a ProblemDetail body. You can access it and modify it:

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
        MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {

    Map<ObjectError, String> messages = 
            ex.resolveErrorMessages(getMessageSource(), LocaleContextHolder.getLocale());

    ProblemDetail problemDetail = ex.getBody();
    problemDetail.setProperty("validation-errors", ...);

    return super.handleMethodArgumentNotValid(ex, headers, status, request);
}

We only use createProblemDetail for lower level exceptions that aren't from any of the web modules, and therefore cannot implement ErrorResponse.

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.

Comment From: tech-conqueror

As Brian mentioned, we don't include such details by default because it exposes implementation details. However, there are a couple of ways to customize this.

The easiest one is to use the ResourceBundle support, and add a problemDetail.title.MethodArgumentNotValidException property. You'll see in the documentation that we expose the list of global errors at {0} and the list of field errors at {1}.

If you want more control, you can override the appropriate exception handling method. Note that you don't need createProblemDetail, because all exceptions in spring-web and spring-webmvc implement ErrorResponse, and already contain a ProblemDetail body. You can access it and modify it:

```java @Override protected ResponseEntity handleMethodArgumentNotValid( MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {

Map messages = ex.resolveErrorMessages(getMessageSource(), LocaleContextHolder.getLocale());

ProblemDetail problemDetail = ex.getBody(); problemDetail.setProperty("validation-errors", ...);

return super.handleMethodArgumentNotValid(ex, headers, status, request); } ```

We only use createProblemDetail for lower level exceptions that aren't from any of the web modules, and therefore cannot implement ErrorResponse.

Hi @rstoyanchev, could you please give an example of how we can customize the ProblemDetail using the first approach you mentioned in this comment?

.