@ControllerAdvice in Spring MVC — Global Exception Handling
Fast recall
Quick revision
Core answer
Understanding of centralized exception handling in production Spring Boot REST APIs
Handling exceptions in every controller method individually instead of using a global handler, leading to inconsistent error responses
Demonstrate a complete @ControllerAdvice example with a structured error DTO, proper HTTP status codes, and mention that it supports @Order for multiple advice classes
Interview-ready guide
Interview answer
For example, OrderNotFoundException can be mapped to 404 ProblemDetail and DuplicateOrderException to 409. Validation exceptions can produce field errors. An unrecognized exception may be left to Spring Boot's normal error handling or caught by a carefully logged final handler; it should not be silently converted to a misleading 400.
@ControllerAdvice in Spring MVC — Global Exception Handling
Direct Answer
@ControllerAdvice declares cross-controller advice such as @ExceptionHandler, @InitBinder, and @ModelAttribute methods. It can be scoped to selected annotations, packages, or controller types. @RestControllerAdvice combines it with @ResponseBody so exception-handler return values are normally written as response bodies.
Code Example
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex, HttpServletRequest request) {
var error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
LocalDateTime.now(),
request.getRequestURI()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(Exception.class) // Catch-all for unexpected errors
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex, HttpServletRequest request) {
var error = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"An unexpected error occurred", // Don't expose internals
LocalDateTime.now(),
request.getRequestURI()
);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
record ErrorResponse(int status, String message, LocalDateTime timestamp, String path) {}
Common Mistakes & Pitfalls
- Handling exceptions inside controllers: Freshers often write try-catch blocks in every controller method instead of letting exceptions bubble up to @ControllerAdvice, resulting in duplicated error-handling code and inconsistent responses.
- Returning stack traces to clients: Exposing ex.printStackTrace() or raw exception messages in production leaks internal implementation details and is a security risk — use generic messages for unexpected errors.
- Forgetting HttpServletRequest parameter: Not injecting HttpServletRequest in handler methods means you can't include the request path in error responses, making client-side debugging harder.
- Not handling generic Exception: If you only handle specific exceptions, unhandled ones will return Spring's default Whitelabel error page, breaking your API contract.
Check your understanding
Answer these without looking back at the article.
- What is the difference between @ControllerAdvice and @RestControllerAdvice?
- How do you return field-level validation errors from @ControllerAdvice?
- What is ResponseEntityExceptionHandler?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.