Search code examples
javaspring-rest

Spring REST @ResponseStatus with Custom exception class does not change the return Status code


I have a exception class like follows

@ResponseStatus(value=HttpStatus.UNPROCESSABLE_ENTITY, reason="Unprocessable Entity")  // 422
public class UnprocessableEntityException extends RuntimeException {
}

Now the status is not returned as 422 unless I write a specific handler in the Controller class like :

@ExceptionHandler(UnprocessableEntityException.class)
    @ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
    public String handleException(Exception ex) {
...
}

As I understand I should not need @ExceptionHandler in first place, not sure what am I missing.


Solution

  • Throwing a @ResponseStatus annotated exception from a controller method should be enough for the framework to write the HTTP status code - no @ExceptionHandler necessary.

    The following will write a 422 Status on hitting the webapp root as expected:

    @Controller
    public class ExceptionController {
    
        @RequestMapping("/")
        public void action() {
            throw new ActionException();
        }
    
        @ResponseStatus(value = HttpStatus.UNPROCESSABLE_ENTITY, reason = "nope")
        public static class ActionException extends RuntimeException {}
    }
    

    This works courtesy of the ResponseStatusExceptionResolver which is created by Spring MVC by default - if it's not working for you, my guess is that this default exception resolver has been removed (by e.g. overriding WebMvcConfigurationSupport.configureHandlerExceptionResolvers or otherwise configuring your context's HandlerExceptionResolvers so that the ResponseStatusExceptionResolver is trumped.)