Exception Handling
Build production-grade exception handling in Spring Boot — @ControllerAdvice, @ExceptionHandler, ProblemDetail, and consistent error responses across your entire API.
Last reviewed: January 2025
🔍 What Is It?
Spring's exception handling mechanism lets you centralize error handling in one place.
Key components:
- →
@ControllerAdvice/@RestControllerAdvice— global handler applied to all controllers - →
@ExceptionHandler(ExceptionType.class)— handles a specific exception type - →
ResponseEntityExceptionHandler— base class that handles Spring MVC exceptions - →
ProblemDetail(Spring Boot 3.x) — RFC 7807 standardized error format
Exception hierarchy to handle:
- →Your custom exceptions (
ResourceNotFoundException,BusinessException) - →Spring validation:
MethodArgumentNotValidException(from@Valid) - →Spring MVC:
MethodArgumentTypeMismatchException,MissingServletRequestParameterException - →Spring Security:
AccessDeniedException,AuthenticationException - →Hibernate:
ConstraintViolationException,DataIntegrityViolationException
🎯 Why Do We Need It?
Without global exception handling:
- →Unhandled exceptions return 500 Internal Server Error with a stack trace (security risk)
- →Different parts of the API return different error formats
- →Clients can't reliably parse error responses
- →Debugging is harder because errors aren't logged consistently
With @ControllerAdvice:
- →Consistent JSON error format across all endpoints
- →Correct HTTP status codes (400 for validation, 404 for not found, 409 for conflicts)
- →No stack traces in responses (security)
- →Centralized logging of errors
🏗️ What Happens in Real Projects?
Every production Spring Boot API has a global exception handler. Standard pattern:
- →
ResourceNotFoundException→ 404 Not Found - →
ValidationException→ 400 Bad Request with field errors - →
BusinessException→ 422 Unprocessable Entity - →
AccessDeniedException→ 403 Forbidden - →
Exception(catch-all) → 500 Internal Server Error (log it, don't expose details)
⚙️ How It Works
When an exception is thrown from a controller (or service/repository called by a controller):
- Spring's DispatcherServlet catches it
- Looks for a matching @ExceptionHandler in the current controller first
- Then looks in @ControllerAdvice classes
- The first matching handler handles it
- Returns the ResponseEntity from the handler method
💻 Example
Production Exception Handling — Complete global exception handler with consistent error responses.
🤔 Common Confusions
❓ @ControllerAdvice vs @RestControllerAdvice — difference?
@RestControllerAdvice = @ControllerAdvice + @ResponseBody. Use @RestControllerAdvice for REST APIs — it automatically serializes your return value to JSON. @ControllerAdvice is for MVC apps where you might return view names.
❓ Why does my @ExceptionHandler not catch Spring Security exceptions?
Spring Security exceptions (AccessDeniedException, AuthenticationException) are handled by the security filter chain BEFORE reaching the DispatcherServlet. To handle them, implement AuthenticationEntryPoint (for 401) and AccessDeniedHandler (for 403) and register them in your SecurityFilterChain.
🚨 Common Production Issues
Stack traces returned in error responses — the catch-all handler must not include ex.getMessage() for unexpected exceptions
Validation errors not returning field details — override handleMethodArgumentNotValid in ResponseEntityExceptionHandler
DataIntegrityViolationException from DB constraints returning 500 — catch it and return 409 Conflict
Error responses not in consistent format — establish one ErrorResponse record and use it everywhere
✅ Best Practices
Always have a catch-all @ExceptionHandler(Exception.class) that returns 500 without exposing internals
Log unexpected exceptions with full stack trace; log expected exceptions at WARN level
Use RFC 7807 ProblemDetail format (Spring Boot 3.x) for standards-compliant error responses
Include a request ID in error responses for correlation with logs
Never expose stack traces, class names, or SQL in error responses
🏛️ Architect's Note
Error handling is part of your API contract. Define your error format early and document it in your OpenAPI spec. Clients need to handle errors reliably — if your format changes, you break them. Use RFC 7807 Problem Details (built into Spring Boot 3.x with spring.mvc.problemdetails.enabled=true) for a standards-compliant format that clients can parse without custom code.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
↗ Where this topic fits
Spring Boot Technology Guide
Return to the Spring Boot learning hub.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Spring Boot references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Spring Boot learning path
Browse the full Spring Boot topic collection and learning order on SplashRide.
Spring Boot Interview Prep
Practice Spring Boot interview questions and scenario-based answers.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Controllers
Master Spring MVC Controllers — the web layer that handles HTTP requests, maps URLs to methods, and returns responses in enterprise REST APIs.
Request Mapping
Master Spring MVC request mapping - how to map HTTP requests to controller methods using @RequestMapping, @GetMapping, @PostMapping, and the full range of mapping options.