handling wrapped exceptions in spring mvc
Unfortunately, UnrecognizedPropertyException
is a subtype of IOException
. The RequestResponseBodyMethodProcessor
that handles the @RequestBody
(I assume that's where the exception occurs) has special handling for IOException
(interpreting as a failure of the request input stream), wrapping it in a HttpMessageNotReadableException
. Additionally, the HttpMessageConverter
interface is specified to throw HttpMessageNotReadableException
if there is a conversion error during read
.
You're going to have to deal with that no matter what (if Jackson threw unchecked exceptions instead, things might have been different).
Fortunately, since 4.3, Spring MVC's ExceptionHandlerMethodResolver
(which processes @ExceptionHandler
) can unwrap the cause
of exceptions (see SPR-14291). As such, assuming you do not have a handler for any exceptions in the inheritance hierarchy of HttpMessageNotReadableException
, your handler method
@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
...
}
will be used to handle the exception. This happens after Spring MVC looks for a handler method that could handle a HttpMessageNotReadableException
, then unwraps the nested exception with Throwable#getCause
and tries the lookup again.
In pre-4.3, or if you do have a handler for an exception type in HttpMessageNotReadableException
's inheritance hierarchy, you can always delegate after extracting the cause yourself.
@ExceptionHandler
public String handle(HttpMessageConversionException e) throws Throwable {
Throwable cause = e.getCause();
if (cause instanceof UnrecognizedPropertyException) {
handle((UnrecognizedPropertyException) cause);
}
...
}
public String handle(UnrecognizedPropertyException e) {
...
}