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

AspectDetails
TypesChecked vs Unchecked, Business vs Technical
Best PracticesSpecific types, meaningful messages, proper context
Spring Integration@ControllerAdvice, ResponseStatusException
Anti-patternsGeneric 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)
Code
Loading 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)
Code
Loading syntax highlighter...

Mental Model: Exception Hierarchy

TEXT(28 lines)
Code
Loading syntax highlighter...

šŸ”¬ Deep Dive

Pattern 1: Base Exception Design

JAVA(67 lines)
Code
Loading syntax highlighter...

Pattern 2: Domain-Specific Exceptions

JAVA(94 lines)
Code
Loading syntax highlighter...

Pattern 3: Validation Exceptions

JAVA(54 lines)
Code
Loading syntax highlighter...

Pattern 4: Technical Exceptions

JAVA(46 lines)
Code
Loading syntax highlighter...

Pattern 5: Spring Boot Integration

JAVA(122 lines)
Code
Loading syntax highlighter...

Pattern 6: Exception Factory

JAVA(43 lines)
Code
Loading syntax highlighter...

āš ļø Common Mistakes

Mistake 1: Catching and Swallowing

JAVA(22 lines)
Code
Loading syntax highlighter...

Mistake 2: Generic Exceptions

JAVA(7 lines)
Code
Loading syntax highlighter...

Mistake 3: Exception for Flow Control

JAVA(14 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
Why are orders being created with invalid state?

āœ… Solution:

Three critical problems:

  1. Exception swallowed - The catch block logs but doesn't rethrow, so the transaction commits
  2. No rollback trigger - @Transactional only rolls back on uncaught exceptions (by default RuntimeException)
  3. Misleading return - User gets success message even when checkout partially failed
Correct approach:
JAVA(34 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
āœ… Solution:
JAVA(77 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
āœ… Solution:
JAVA(100 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
āœ… Solution:
JAVA(84 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
āœ… Solution:
JAVA(91 lines)
Code
Loading 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)
Code
Loading syntax highlighter...
āœ… Solution:
JAVA(121 lines)
Code
Loading 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:
  1. Create base ApplicationException with common fields (code, context, timestamp)
  2. Split into BusinessException (4xx, user-facing) and TechnicalException (5xx, logged)
  3. Create domain-specific exceptions (OrderException, PaymentException)
  4. Use factory methods for consistent creation
  5. Integrate with global handler for uniform API responses

šŸ“ Summary

TypePurposeHTTP StatusLog Level
BusinessExceptionUser can fix4xxWARN
ValidationExceptionInvalid input400WARN
NotFoundExceptionResource missing404WARN
TechnicalExceptionSystem issue5xxERROR

šŸ“… Review Schedule for This Article

DayTaskTime
Day 1Review exception hierarchy mental model diagram5 min
Day 3Redo Exercise 1 (Design Exception Hierarchy)15 min
Day 7Answer interview questions without looking10 min
Day 14Redo Debug This (Swallowed Exception)15 min
Day 30Audit exception handling in one service of your codebase20 min

Next: [Part 15: Result Pattern]