2

I have recently migrated my application from spring boot 2.1 to spring boot 3.0. But the problem is that now there are endpoints which are not giving the same response when an error happens, instead I get something like this:

 {
        "type": "about:blank",
        "title": "Bad Request",
        "status": 400,
        "detail": "Failed to convert 'id' with value: 'territory'",
        "instance": "/webfront/administration/book/territory"
    }

I accomplished this by adding a @ControllerAdvice class that extends from ResponseEntityExceptionHandler.

However I require some other information, the expected one would be like this:

{
    "type": "about:blank",
    "title": "Bad Request",
    "status": 400,
    "detail": "Failed to convert 'id' with value: 'territory'",
    "instance": "/webfront/administration/book/territory",
    "timestamp": "2023-04-15 12:02:21",
    "code" : 24
}

Here is the implementation of my controller advice that should be applied globally (for the example there is only one exception but in reality there are several).

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    private static ErrorResponse mapToErrorResponse(Exception e, ApplicationError applicationError, String errorMessage, HttpStatus status) {
        return ErrorResponse.builder(e, status, errorMessage)
                .property("code", String.valueOf(applicationError.getCode()))
                .property("timestamp", Instant.now())
                .build();
    }

    @ExceptionHandler(FileAccessException.class)
    public ErrorResponse fileAccessException(FileAccessException fae) {
        log.error("File access Exception", fae);
        return mapToErrorResponse(fae, fae.getApplicationError(), fae.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
...
}

For some reason this handler is not being detected by spring and the exceptions body continue as the first example without my custom data.

I also have another problem regarding my UrlAuthenticationFailureHandler before when the user tried to access an unauthorized route the exception was handled now the body is always empty. I tried adding this config entries to my application.yml but it didn't make any difference:

server:
   error:
     include-message: ALWAYS
     include-stacktrace: ALWAYS
mvc:
   problemdetails:
     enabled: true
Brian Clozel
  • 56,583
  • 15
  • 167
  • 176

1 Answers1

0

did you see the log.error("File access Exception", fae); ...

no, nothing @xerx593

Assuming:

  • your logging is set-up correct and level >= error
  • and @ControllerAdvice picked up correctly

..that means:

It was no FileAccessException (but another one, ..set a breakpoint!)

Look at the impl of ResponseEntityExceptionHandler, it registers exception handler for "bunch of"/many types of Exceptions and is "the default".

Configured via ProblemDetailsExceptionHandler(web|webflux), but also (via inheritance) with your custom implementation.

To get "the best" out of your "exception handler" (consider application.properties e.g.), follow the tips outlined here (it says "reactive", but: potayto-potahto;):

  • Keep/bear the super Implementation in mind:
    • existing handler interfaces
    • utilize protected methods
  • Extend your "Error" class from ErrorResponseException
xerx593
  • 12,237
  • 5
  • 33
  • 64