Suppose I like the default error handling of Spring Boot for Spring Web MVC, but I just want to return a different HTTP status for specific exceptions: for instance, I would like to return 404 when a FileNotFoundException is thrown, instead of the default 500.

The quickest way to do this would be to define a @Bean implementing ErrorAttributes, by extending DefaultErrorAttributes changing just addStatus(Map<String, Object>, RequestAttributes) to return 404 in case getError(WebRequest) returns a FileNotFoundException. However, this is not currently possible because addStatus(Map<String, Object>, RequestAttributes) is private!

Other methods like addErrorDetails(Map<String, Object>, WebRequest, boolean), addErrorMessage(Map<String, Object>, Throwable) and addStackTrace(Map<String, Object>, Throwable) could simplify quick customisations if they were protected...

Comment From: mauromol

I just saw there's a further complication: DefaultErrorAttributes and BasicErrorController have duplicated logic to determine the HTTP status to put in the response body and in the response header respectively. They are defined in org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController.getStatus(HttpServletRequest) and org.springframework.boot.web.servlet.error.DefaultErrorAttributes.addStatus(Map<String, Object>, RequestAttributes) respectively and they even behave differently in some corner cases (for instance when javax.servlet.error.status_code request attribute is null). IMHO, since BasicErrorController uses an ErrorAttributes instance, a reasonable (to be documented) convention could be that it first tries to extract the status from the ErrorAttributes insance (keyed by "status") and then falls back to the standard (duplicated) logic if not set.

In this way properly customising just the ErrorAttributes could fully drive the error response.

Comment From: wilkinsona

My understanding of the Servlet spec is that javax.servlet.error.status_code should never be null when the request reaches the error controller as an error dispatch is being performed at that point. In other words the inconsistency shouldn't be a problem in practice.

That said, your point about similar logic existing in two places still stands. Ideally, the API would guide things towards an arrangement that would minimise the possibility of the error attributes implementation and the error controller implementation disagreeing on the status of the response. That could be done by retrieving the value that's keyed by status from the ErrorAttributes or, perhaps, via a new method on ErrorAttributes that passes in the status that the error controller is going to set on the response. The former probably does a better job of minimising the chance of an inconsistency while the latter avoids requiring the response status to have the key status.

I see fixing the potential status inconsistency and making things more extensible as two separate problems. I've opened https://github.com/spring-projects/spring-boot/issues/20504 to tackle the former and we can use this issue to track the latter.

Comment From: maxxyme

Hello,

Currently facing the same issue, how can I work around this?