Validation & Exception Handling
@ControllerAdvice and @ExceptionHandler — Global Exception Handling
Catching application exceptions centrally and formatting clean error responses.
Introduction
In a typical multi-tier enterprise application, errors can occur at any layer (repositories, services, or controllers). Rather than cluttering every controller mapping with try-catch blocks or exposing raw stack traces to client callers, Spring MVC provides a robust, aspect-oriented way to handle exceptions globally using @ControllerAdvice and @ExceptionHandler.
Why It Matters
Uncaught exceptions will result in standard internal server error responses (HTTP 500) that leak underlying stack traces or database query details to clients, creating security liabilities. Centralizing exception handling allows consistent error formatting, precise HTTP status returns, and proper logging of system errors.
Real-World Analogy
Think of global exception handling like a customer service desk in a retail store. If a customer encounters an issue with a product, the department cashiers (individual controllers) don't resolve the refund policies themselves. Instead, any dispute or exception is directed to a specialized desk (the global advice handler), which handles all issue categories consistently using preset policies.
How It Works
The mechanism relies on Spring components:
@ControllerAdvice(or@RestControllerAdvice): A specialization of@Componentthat applies globally to all controllers. It intercepts responses and maps exceptions.@ExceptionHandler: Declared on methods within the advice class to specify which specific Java exception classes the method will process.
When an exception occurs during request execution, Spring stops standard handling, looks up the registered exception mapping, executes the matching handler method, and serializes its return value (like a DTO or ResponseEntity) directly back to the HTTP client.
Practical Example
Here is how to set up a comprehensive, custom global error handling payload structure:
1. Define a Standard Error Response DTO
2. Implement the RestControllerAdvice Class
Quick Quiz
Q1: What is the main difference between @ControllerAdvice and @RestControllerAdvice?
A) @RestControllerAdvice handles only security exceptions
B) @RestControllerAdvice automatically appends @ResponseBody to handler methods so values serialize to JSON
C) @ControllerAdvice has been deprecated since Spring Boot 2.0
D) @RestControllerAdvice is only for asynchronous routing
Answer: B — Just like @RestController combines @Controller and @ResponseBody, @RestControllerAdvice combines @ControllerAdvice and @ResponseBody.
Q2: How does Spring resolve conflicts if multiple @ExceptionHandler methods could match a thrown exception (e.g. CustomException extending RuntimeException)?
A) It throws a startup ambiguity exception
B) It chooses the most specific exception type handler in the hierarchy
C) It executes them randomly
D) It calls the generic Exception handler first
Answer: B — Spring resolves the closest matching class mapping in the class inheritance hierarchy.
Scenario-Based Challenge
Production Scenario:
Your application exposes an endpoint where users upload user profiles. If a database query locks or times out, a Hibernate/JDBC transaction exception is thrown. How do you prevent clients from getting raw SQL details or database schema table names in the error response?
View Solution
Create a specific handler mapping in your @RestControllerAdvice class for JDBC/persistence base exceptions (like DataAccessException or TransactionException) or rely on a generic Exception.class fallback. In the handler method, log the error details locally (e.g. via Slf4j logger) with a unique tracker UUID, but return a sanitized ErrorResponse with a generic error code and message: "A database issue occurred. Reference ID: {UUID}". This hides internal system topologies while allowing system administrators to trace the error using the ID in the server logs.
Interview Questions
1. Can you declare multiple ControllerAdvice classes in a single Spring Boot project? How is execution order managed?
Yes, you can declare multiple advices. Spring manages ordering using the @Order annotation or by implementing the Ordered interface. Advices with lower values (e.g. @Order(1)) run first. If not ordered explicitly, execution depends on the classpath scanning order.
2. How can you retrieve the current request details (like URI or client host) inside a global exception handler method?
You can add parameters of type WebRequest or HttpServletRequest directly to the exception handler method signature. Spring will inject the current request context, allowing you to extract headers, URIs, query strings, and other client attributes.
Production Considerations
Always log the stack trace in your fallback handler so developers can debug failures. However, do not log sensitive data (like card numbers or passwords) that were passed in request payloads. Cleanly map security exceptions (e.g., Spring Security's AccessDeniedException) to HTTP 403 Forbidden to maintain a standard security perimeter.