I am using a Default AnnotationMethodHandlerAdapter which I believe should enable support for @ExceptionHandler. Unluckily, a ServletRequestBindingException is thrown if a call to a handler method like this below is coming in - and not Exception handler is invoked.
@RequestMapping(value = "/v1/products/{code}", method = RequestMethod.GET, headers = "Accept=application/xml,application/json")
@ResponseBody
public ProductDemoDTO getProductByCode(@PathVariable final String code,
@RequestParam(required = false, defaultValue = "BASIC") final String options)
{
//omitted
}
Here teh ExceptionHandler, never called:
@ExceptionHandler(Throwable.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
//TODO not being called?
public void handleException(final Exception e, final HttpServletRequest request, final Writer writer) throws IOException
{
writer.write(String.format("{\"error\":{\"java.class\":\"%s\", \"message\":\"%s\"}}", e.getClass(), e.getMessage()));
}
Does anyone know why the ExceptionHandler is not called?
you cannot handle it with spring custom implementation.
it may not an elegant solution but you still can catch it with web.xml <error-page>
tag. you can catch exception type or error code from here.
This issue is fixed in Spring 3.2. You can create a global exception handler class with the @ControllerAdvice
annotation. Then in that class add an @ExceptionHandler
method to handle the ServletRequestBindingException and return a custom response body. Example:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ServletRequestBindingException.class)
public ResponseEntity<String> handleServletRequestBindingException(ServletRequestBindingException ex) {
return new ResponseEntity<String>("MISSING REQUIRED HEADER",HttpStatus.PRECONDITION_REQUIRED);
}
}
For more information check the spring mvc docs: 17.11 Handling exceptions
Unfortunately, @ExceptionHandler
methods are only invoked for exceptions that are thrown from within the handler method. ServletRequestBindingException
is an infrastructure exception that is thrown whilst trying to invoke a handler method, and if the handler method itself cannot be invoked for whatever reason, then the @ExceptionHandler
is not used.
There doesn't really seem to be a nicer way to handle this. Without knowing what's causing your ServletRequestBindingException
, though, it's hard to advise.
Aaand thanks to Juergen Hoeller this has been solved today and should appear in Spring 4.3.
Please refer to the issue:
https://jira.spring.io/browse/SPR-11106