Search code examples
springspring-bootrestexceptionexceptionhandler

What Exception class type does Spring Boot throw when the user tries to access a REST endpoint whose path does not exist at the @RestController?


When using @ControllerAdvice and @ExceptionHandler annotations, along with some handler methods, I'm able to catch events from Exceptions thrown both by myself as by Spring Boot internally. For the handler to know which exception event to catch, I can use both the specific nested Exception class as a generic Exception class, as argument, at the handler... and it will catch the corresponding event.

I've not managed to catch one specific Exception event though, the one in which the user requests resources from a REST endpoint or path that doesn't exist at the @RestController... a "bad path". It just returns a 404 NOT FOUND response payload as a JSON, but I can't catch that at my @ControllerAdvice @ExceptionHandler method in order to change the Response for that specific Exception event. Not even when using the top-level Exception.class can I catch this event... and I don't know the specific nested Exception class that Spring Boot uses when it throws this specific event, either.

Does anyone know what's the Exception class type whose instance Spring Boot throws when the user requests a "bad path" (inexistent endpoint) to the @RestController of an application ?

enter image description here


Solution

  • Finally I was able to adapt successfully 2 solutions for this use-case exceptional flow !! :D

    SOLUTION 1: By creating an ErrorController and implementing a method for the /error servlet mapping path. Inside, you can create and return your ResponseEntity already, or, in my case, I chose to throw an instance of my custom PathNotFoundException, so that later I could catch its event at my @AdviceController @ExceptionHandler method and mount my response payload data there. The disadvantage to this solution is that you can't get the path the user tried to access from the HttpServletRequest, as the path available will be the intermediate "/error" path from the ErrorController and not the original path the user tried to get any resources from. But, at least, with this solution, you can catch the exception event (at the ErrorController) and direct the flux to your custom handler to create and return a custom ResponseEntity and payload data from there.

    enter image description here

    enter image description here

    enter image description here
    .
    .
    .
    SOLUTION 2: This is the best solution. For avoiding the redirectioning to and from the ErrorController, and for not having to implement a custom /error method there, you can simply:

    2.1: add these two props at the application.properties:

    spring.mvc.throw-exception-if-no-handler-found=true
    spring.web.resources.add-mappings=false
    

    2.2: at your @AdviceController @ExceptionHandler method you then will be able to catch the NoHandlerFoundException event, as when catching any other exception event there, then mounting your ResponseEntity and payload data. And, most importantly, as there won't be the redirectioning to and from the ErrorController (/error), you'll be able to get the original path the user tried to access from the HttpServletRequest.

    enter image description here

    enter image description here

    enter image description here

    Thanks to everyone who helped solve this simple, although recurring, issue, so that others can learn from it and not waste 24h, searching for a solution, as I just did ;D

    See ya.

    Daniel Pinheiro
    danielpm1982.com