0

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

Daniel Pinheiro
  • 988
  • 8
  • 14

4 Answers4

0

I managed to add a custom invalid route exception using two configurations in the past on a project, not sure if its relevant to Spring 3.x:

spring.mvc.throw-exception-if-no-handler-found=true
spring.mvc.static-path-pattern=/static

These properties and a corresponding ExceptionHandler for NoHandlerFoundException allowed me to add my own custom response handler for unmapped routes.

Gate D
  • 1
  • 1
0

Answer to your question: NoHandlerFoundException

Your answer resides in "ResponseEntityExceptionHandler.class", which is responsible for handling every possible Web Exceptions raised through Spring Web Framework and transforming them to HTTP Response.

You would find a common place holder method tagged with @ExceptionHandler to handle all such exceptions, and all exception classes would be exclusively mapped to that method inside annotation @ExceptionHandler.

Philip Dilip
  • 181
  • 2
  • 4
0

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

Daniel Pinheiro
  • 988
  • 8
  • 14
0

In Spring Boot, when a user tries to access a REST endpoint whose path does not exist at the @RestController level, Spring Boot throws a org.springframework.web.servlet.NoHandlerFoundException exception.

This exception is thrown when Spring is unable to find a handler for the request, which usually means that the requested URL does not match any of the registered endpoints. This exception is usually handled by Spring's DefaultHandlerExceptionResolver, which will return an HTTP 404 error response to the client.