Java
Exception Hierarchy Design
Well-designed exceptions are crucial for maintainable error handling. This article covers how to design exception hierarchies that communicate intent, enable proper handling, and integrate cleanly with Spring Boot.
📋 At a Glance
| Aspect | Details |
|---|---|
| Types | Checked vs Unchecked, Business vs Technical |
| Best Practices | Specific types, meaningful messages, proper context |
| Spring Integration | @ControllerAdvice, ResponseStatusException |
| Anti-patterns | Generic exceptions, empty catch, exception swallowing |
🎯 What You'll Learn
- Exception hierarchy design principles
- Business vs technical exceptions
- Exception context and meaningful messages
- Spring Boot integration with @ControllerAdvice
- Anti-patterns to avoid
Production Story: The Generic Exception Disaster
A payment system used generic exceptions everywhere:
JAVA(17 lines)CodeLoading syntax highlighter...
Problems:
- No way to distinguish recoverable vs fatal errors
- Lost original cause and context
- Generic error messages to users
- No specific logging or metrics
- Impossible to retry appropriately
The fix: Well-designed exception hierarchy:
JAVA(26 lines)CodeLoading syntax highlighter...
Mental Model: Exception Hierarchy
TEXT(28 lines)CodeLoading syntax highlighter...
🔬 Deep Dive
Pattern 1: Base Exception Design
JAVA(67 lines)CodeLoading syntax highlighter...
Pattern 2: Domain-Specific Exceptions
JAVA(94 lines)CodeLoading syntax highlighter...
Pattern 3: Validation Exceptions
JAVA(54 lines)CodeLoading syntax highlighter...
Pattern 4: Technical Exceptions
JAVA(46 lines)CodeLoading syntax highlighter...
Pattern 5: Spring Boot Integration
JAVA(122 lines)CodeLoading syntax highlighter...
Pattern 6: Exception Factory
JAVA(43 lines)CodeLoading syntax highlighter...
⚠️ Common Mistakes
Mistake 1: Catching and Swallowing
JAVA(22 lines)CodeLoading syntax highlighter...
Mistake 2: Generic Exceptions
JAVA(7 lines)CodeLoading syntax highlighter...
Mistake 3: Exception for Flow Control
JAVA(14 lines)CodeLoading syntax highlighter...
🐛 Debug This: The Swallowed Exception
A developer reports: "Orders randomly disappear after checkout! The user sees 'Order placed successfully' but no order is created."
JAVA(34 lines)CodeLoading syntax highlighter...
Why are orders being created with invalid state?
✅ Solution:
Three critical problems:
- Exception swallowed - The catch block logs but doesn't rethrow, so the transaction commits
- No rollback trigger -
@Transactionalonly rolls back on uncaught exceptions (by default RuntimeException) - Misleading return - User gets success message even when checkout partially failed
Correct approach:
JAVA(34 lines)CodeLoading syntax highlighter...
The lesson: Never swallow exceptions in transactional methods. Either rethrow or throw a new exception to trigger rollback. Use
rollbackFor when dealing with checked exceptions.💻 Exercises
Exercise 1: Design Exception Hierarchy
⭐ Difficulty: Easy | ⏱️ Time: 15 minutes
Task: Design an exception hierarchy for a user management domain.
JAVA(8 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(77 lines)CodeLoading syntax highlighter...
Exercise 2: Exception Handler
⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes
Task: Create a Spring
@ControllerAdvice that handles exceptions with proper logging and response formatting.JAVA(5 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(100 lines)CodeLoading syntax highlighter...
Exercise 3: Exception with Context
⭐⭐ Difficulty: Medium | ⏱️ Time: 15 minutes
Task: Create an exception that carries rich context for debugging.
JAVA(6 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(84 lines)CodeLoading syntax highlighter...
Exercise 4: Exception Factory
⭐⭐⭐ Difficulty: Medium-Hard | ⏱️ Time: 20 minutes
Task: Create an exception factory with fluent API for common scenarios.
JAVA(5 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(91 lines)CodeLoading syntax highlighter...
Exercise 5: Transactional Exception Handling
⭐⭐⭐⭐ Difficulty: Hard | ⏱️ Time: 25 minutes
Task: Design exception handling for a complex transactional operation with compensating actions.
JAVA(7 lines)CodeLoading syntax highlighter...
✅ Solution:
JAVA(121 lines)CodeLoading syntax highlighter...
🎤 Interview Questions
Q1: Checked vs Unchecked exceptions - when to use each?
Answer:
- Checked: Recoverable conditions, caller CAN and SHOULD handle (IOException, SQLException)
- Unchecked: Programming errors or unrecoverable (NullPointerException, IllegalArgumentException)
Modern practice: Prefer unchecked for most cases, as checked exceptions:
- Clutter method signatures
- Often caught and wrapped anyway
- Don't work with lambdas/streams
Q2: How do you design exception hierarchy for an application?
Answer:
- Create base
ApplicationExceptionwith common fields (code, context, timestamp) - Split into
BusinessException(4xx, user-facing) andTechnicalException(5xx, logged) - Create domain-specific exceptions (OrderException, PaymentException)
- Use factory methods for consistent creation
- Integrate with global handler for uniform API responses
📝 Summary
| Type | Purpose | HTTP Status | Log Level |
|---|---|---|---|
| BusinessException | User can fix | 4xx | WARN |
| ValidationException | Invalid input | 400 | WARN |
| NotFoundException | Resource missing | 404 | WARN |
| TechnicalException | System issue | 5xx | ERROR |
📅 Review Schedule for This Article
| Day | Task | Time |
|---|---|---|
| Day 1 | Review exception hierarchy mental model diagram | 5 min |
| Day 3 | Redo Exercise 1 (Design Exception Hierarchy) | 15 min |
| Day 7 | Answer interview questions without looking | 10 min |
| Day 14 | Redo Debug This (Swallowed Exception) | 15 min |
| Day 30 | Audit exception handling in one service of your codebase | 20 min |
Next: [Part 15: Result Pattern]