Spring Boot Filters Exception Handling

Akhilesh Sharma
3 min readJan 26, 2025

--

Photo by Walkator on Unsplash

Spring boot provides a mechanism of default exception handler. This come packaged with the framework. But, do we need all applications built to adhere to the format provided by default in spring. Every application is different and the format of the error responses vary significantly.

Most common way of handling the exceptions in Spring boot is by creating a Global Exception Handler.

@RestControllerAdvice
public class GlobalExceptionHandler {
//Sample Exception Handler
@ExceptionHandler(InvalidRequestException.class)
public ResponseEntity<ApiErrorResponse> handleInvalidRequestException(InvalidRequestException exception) {
HttpStatus status = HttpStatus.BAD_REQUEST;
ApiErrorResponse errorResponse = ApiErrorResponse.builder()
.message(exception.getMessage())
.status(status).build();
return new ResponseEntity<>(errorResponse, status);
}
}

I am assuming that you are already familiar with the concept of handling exceptions in Spring using Controller Advice.

Request Propagation

Above flows entails the journey of the request, starting from the web application server all the way to the controller.

Exception Handling.

Spring handles the exception in the above order. It first starts with the local first concept

  • Checks if there is a local exception handler associated to the exception that is being raised. If yes, then uses the local exception handler to handle and return response.
  • If not, then it checks if there is a ControllerAdvice registered for the application and applicable exception handler is present. If yes, proceeds with the execution.
  • If the controller advice does not have the handler for the exception, it checks if there is a response status associated with the exception on the ExceptionHandlerExceptionResolver. If yes, utilizes the Response Status Exception Resolver to resolve the exception.
  • If all else fails, then falls back to the default handler exception resolver. It falls back to the Basic Error Controller present for Spring to return the response back to the client.

All above is just to set in the context for exception handling in Spring. The core focus of this article is to list understand how to handle exceptions in case there was an exception raised before the request even reaches the Dispatcher Servlet.

The application returns a response that is not in alignment with API contracts leading to integration consistency with the client.

Let’s take an example. Consider a situation where you are integrated with Spring Security and implement a JWT filter to handle authentications for principals.

In case of invalid JWT being provided or some run time exception that was raised by the filter, the application should return the response something like this (the response body is dependent on the error response defined by your application).

{
"status": "UNAUTHORIZED",
"message": "Cannot access the resource due to inappropriate access"
}

If there is not handler in the application to handle such exceptions, the application with return a blank response with 403 response code.

There are couple of way to handle this scenario in your application.

  • Within doInternal method, handle the exception and write to HttpServletResponse to adhere to your application standards.
  • Utilize the RestControllerAdvice Global exception handler. This is the one we will be looking into.

The idea to use RestControllerAdvice is to wrap up the doFilter method in a try catch block and use the HandlerExceptionResolver to resolve the exception.

@Component
@Slf4j
public class ExceptionHandlerFilter extends OncePerRequestFilter {

@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver exceptionResolver;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try{
filterChain.doFilter(request, response);
} catch(RuntimeException e){
log.error(e.getMessage(), e);
exceptionResolver.resolveException(request, response, null, e);
}
}
}

Once the filter is registered in your application and placed as primary filter ahead of others automatically catches the exception that are generated by other filters and resolve it using the exception resolver.

Just as an example, if you are using spring security, then add this before the UsernamePasswordAuthenticationFilter in Spring security config.

 @Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.addFilterBefore(this.exceptionHandlerFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(this.jwtFilter, UsernamePasswordAuthenticationFilter.class);

return http.build();
}

I hope you enjoyed the article. Happy learning. Cheers!

--

--

Akhilesh Sharma
Akhilesh Sharma

Written by Akhilesh Sharma

Simple | Goal Oriented | Self-Driven | Ever-Learning | Tech Enthusiast | Cloud Architect

No responses yet