I want to use generic way to manage 5xx error codes, let's say specifically the case when the db is down across my whole spring application. I want a pretty error json instead of a stack trace.
For the controllers I have a @ControllerAdvice
class for the different exceptions and this is also catching the case that the db is stopping in the middle of the request. But this is not all. I also happen to have a custom CorsFilter
extending OncePerRequestFilter
and there when i call doFilter
i get the CannotGetJdbcConnectionException
and it will not be managed by the @ControllerAdvice
. I read several things online that only made me more confused.
So I have a lot of questions:
ExceptionTranslationFilter
but this only handles AuthenticationException
or AccessDeniedException
. HandlerExceptionResolver
, but this made me doubt, I don't have any custom exception to manage, there must be a more obvious way than this. I also tried to add a try/catch and call an implementation of the HandlerExceptionResolver
(should be good enough, my exception is nothing special) but this is not returning anything in the response, i get a status 200 and an empty body. Is there any good way to deal with this? Thanks
So this is what I did:
I read the basics about filters here and I figured out that I need to create a custom filter that will be first in the filter chain and will have a try catch to catch all runtime exceptions that might occur there. Then i need to create the json manually and put it in the response.
So here is my custom filter:
public class ExceptionHandlerFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (RuntimeException e) {
// custom error response class used across my project
ErrorResponse errorResponse = new ErrorResponse(e);
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.getWriter().write(convertObjectToJson(errorResponse));
}
}
public String convertObjectToJson(Object object) throws JsonProcessingException {
if (object == null) {
return null;
}
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
}
And then i added it in the web.xml before the CorsFilter
. And it works!
<filter>
<filter-name>exceptionHandlerFilter</filter-name>
<filter-class>xx.xxxxxx.xxxxx.api.controllers.filters.ExceptionHandlerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>exceptionHandlerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>