Skip to content

ResponseEntityExceptionHandler error handling improvements #33443

@mauromol

Description

@mauromol

I'm implementing a REST API with a ControllerAdvice and planning to use RFC 9457-compliant error responses.
I see what Spring Framework 6+ provides.

In Spring 6 documentation I read this:
https://docs.spring.io/spring-framework/docs/6.0.0/reference/html/web.html#mvc-ann-rest-exceptions-non-standard

You can also extend ProblemDetail to add dedicated non-standard properties. The copy constructor in ProblemDetail allows a subclass to make it easy to be created from an existing ProblemDetail. This could be done centrally, e.g. from an @ControllerAdvice such as ResponseEntityExceptionHandler that re-creates the ProblemDetail of an exception into a subclass with the additional non-standard fields.

Sounds good: the ResponseEntityExceptionHandler provides this method which might be overridden to create my own extension instances of ProblemDetail from the framework-provided ones:

protected ProblemDetail createProblemDetail(
			Exception ex, HttpStatusCode status, String defaultDetail, @Nullable String detailMessageCode,
			@Nullable Object[] detailMessageArguments, WebRequest request) {
  // ...
}

However this method is invoked "for any exception that doesn't implement ErrorResponse", as confirmed by its Javadoc. When, however, the intercepted exception implements ErrorResponse, the ProblemDetail is built inside the handleExceptionInternal method directly, by using ErrorResponse.updateAndGetBody, with no call to the above method and so no hook available to transform it into my own problem detail extension.

Perhaps some protected method that gets the ProblemDetail, the originating exception, the web request, and so on, and returns another ProblemDetail, invoked in both the above places, could make the job. Default implementation could just return the ProblemDetail instance as-is, while an extension could decorate it and return a suitable ProblemDetail extension.

The second doubt I have is this: why does createProblemDetail receive an Exception and not a Throwable? If my ControllerAdvice extending ResponseEntityExceptionHandler wants to also handle Errors (or a generic Throwable), it can't use it to create a ProblemDetail. This is in contrast with ErrorResponse.builder() method, which does accept a Throwable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: webIssues in web modules (web, webmvc, webflux, websocket)status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions