I have a problem with Spring's exception handling for controllers. I have a class annotated with @RestControllerAdvice
with a couple of @ExceptionHandler
's, like this:
@ExceptionHandler(HttpRequestMethodNotSupportedException::class)
fun methodNotSupportedException(
exception: HttpRequestMethodNotSupportedException,
request: HttpServletRequest
): ResponseEntity<ApiError> {
logger().error("Method not supported: {}", exception.message)
val methodNotAllowed = HttpStatus.METHOD_NOT_ALLOWED
val apiError = logAndBuildApiError(request, methodNotAllowed, exception)
return ResponseEntity(apiError, methodNotAllowed)
}
and they work perfectly fine. In this case, when I'm trying to use an non-implemented HTTP method like POST:
{
"requestUri": "/api/v1/items",
"status": 405,
"statusText": "Method Not Allowed",
"createdAt": "2023-01-12T16:50:36.55422+02:00",
"errorMessage": "Request method 'POST' not supported"
}
What I would like to achieve is to handle situations when someone is trying to reach an non-existing endpoint, i.e. the correct one is GET http://localhost:8080/api/v1/items
.
But when I'm trying to reach http://localhost:8080/api/v1/itemss
, which is of course nonexistent, I recieve a regular Spring whitelabel error page, but I would like to receive a JSON like in the former example:
{
"requestUri": "/api/v1/itemss",
"status": 404,
"statusText": "Not Found",
"createdAt": "2023-01-12T16:52:06.932108+02:00",
"errorMessage": "Some error message"
}
How do I implement a @ExceptionHandler
so it could handle exceptions related to non-existing resources?
spring.mvc.throw-exception-if-no-handler-found
works in conjunction withspring.mvc.static-path-pattern
. By default, the static path pattern is /**, which includes the whitelabel error pages that you're seeing.See https://github.com/spring-projects/spring-boot/pull/31660 and https://gitter.im/spring-projects/spring-boot?at=62ba1378568c2c30d30790af and https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.servlet.spring-mvc.static-content
Option one is to set these two properties in your configuration.
Option 2 is to add
@EnableWebMvc
to your spring boot application, and set thespring.mvc.throw-exception-if-no-handler-found
property to true. By addingEnableWebMvc
you'll be getting theWebMvcConfigurationSupport
bean, which will cause Spring not to initialize theWebMvcAutoConfiguration
and thereby not set the static-path-pattern.