spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.63k stars 38.14k forks source link

Simplify mapping of custom exception to an RFC 7807 response in ResponseEntityExceptionHandler #29384

Closed rstoyanchev closed 2 years ago

rstoyanchev commented 2 years ago

ResponseEntityExceptionHandler supports RFC 7807 transparently for any ErrorResponse exception, but as explained in https://github.com/spring-projects/spring-framework/issues/28814#issuecomment-1291212330, what a subclass needs to do to map a custom exception is not as easy as could be. We could add a protected method to create the ProblemDetail and that method could also perform a lookup via MessageSource to resolve the detail:

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

This would allow handling a custom exception like this:

@ExceptionHandler
ResponseEntity<Object> handleMyException(MyException myException, WebRequest request) {

    ProblemDetail body = createProblemDetail(
            HttpStatus.BAD_REQUEST, "My default message", new Object[] {ex.getParam1(), ex.getParam2()});

    // ...

    return handleExceptionInternal(myException, body, null, null, request);
}
biergit commented 2 years ago

Hey @rstoyanchev

on another thought there is also the "title" member for which having an equally convenient i18n measure may be nice. What do you think? Then I read about additional members in the RfC:

If such additional members are defined, their names SHOULD start with a letter (ALPHA, as per [RFC5234], Appendix B.1) and SHOULD consist of characters from ALPHA, DIGIT ([RFC5234], Appendix B.1), and "_" (so that it can be serialized in formats other than JSON), and they SHOULD be three characters or longer.

and wondered if this could be checked by Spring as well or if I'm definitely going to far now? 😃

rstoyanchev commented 2 years ago

Yes, it should be straight forward to do the same for the "title", so I've created #29407.

Additional members are less straight forward as those could be in the "properties" map in ProblemDetail or actual fields on a sub-class. I'll leave those out for now.