spring boot override default REST exception handler
Remove @ResponseStatus
from your method. It creates an undesirable side effect and you don't need it, since you are setting HttpStatus.UNPROCESSABLE_ENTITY
in your ResponseEntity
.
From the JavaDoc on ResponseStatus
:
Warning: when using this annotation on an exception class, or when setting the reason attribute of this annotation, the
HttpServletResponse.sendError
method will be used.With
HttpServletResponse.sendError
, the response is considered complete and should not be written to any further. Furthermore, the Servlet container will typically write an HTML error page therefore making the use of a reason unsuitable for REST APIs. For such cases it is preferable to use aResponseEntity
as a return type and avoid the use of@ResponseStatus
altogether.
I suggest you to read this question: Spring Boot REST service exception handling
There you can find some examples that explain how to combine ErrorController/ ControllerAdvice in order to catch any exception.
In particular check this answer:
https://stackoverflow.com/a/28903217/379906
You should probably remove the annotation @ResponseStatus from the method handleBusinessValidationException.
Another way that you have to rewrite the default error message is using a controller with the annotation @RequestMapping("/error"). The controller must implement the ErrorController interface.
This is the error controller that I use in my app.
@RestController@RequestMapping("/error")public class RestErrorController implements ErrorController{ private final ErrorAttributes errorAttributes; @Autowired public MatemoErrorController(ErrorAttributes errorAttributes) { Assert.notNull(errorAttributes, "ErrorAttributes must not be null"); this.errorAttributes = errorAttributes; }@Overridepublic String getErrorPath() { return "/error";}@RequestMappingpublic Map<String, Object> error(HttpServletRequest aRequest) { return getErrorAttributes(aRequest, getTraceParameter(aRequest));}private boolean getTraceParameter(HttpServletRequest request) { String parameter = request.getParameter("trace"); if (parameter == null) { return false; } return !"false".equals(parameter.toLowerCase());}private Map<String, Object> getErrorAttributes(HttpServletRequest aRequest, boolean includeStackTrace){ RequestAttributes requestAttributes = new ServletRequestAttributes(aRequest); return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);} }