Exception Handling
Proper exception handling ensures your application fails gracefully and provides useful error information.
Exception Hierarchy
Throwable
├── Exception (checked)
│ ├── IOException
│ ├── SQLException
│ └── ServletException
├── RuntimeException (unchecked)
│ ├── NullPointerException
│ ├── IllegalArgumentException
│ ├── IllegalStateException
│ └── YourCustomException
└── Error (JVM errors — don't catch)
├── OutOfMemoryError
└── StackOverflowError
Custom Exceptions
// Base exception for your application
public class ApplicationException extends RuntimeException {
private final String errorCode;
public ApplicationException(String message, String errorCode) {
super(message);
this.errorCode = errorCode;
}
public ApplicationException(String message, String errorCode, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
public String getErrorCode() { return errorCode; }
}
// Specific exceptions
public class ResourceNotFoundException extends ApplicationException {
public ResourceNotFoundException(String resource, Long id) {
super(resource + " not found with id: " + id, "RESOURCE_NOT_FOUND");
}
}
public class DuplicateResourceException extends ApplicationException {
public DuplicateResourceException(String message) {
super(message, "DUPLICATE_RESOURCE");
}
}
public class InsufficientStockException extends ApplicationException {
public InsufficientStockException(Long productId, int requested, int available) {
super("Product " + productId + ": requested " + requested + " but only " + available + " in stock",
"INSUFFICIENT_STOCK");
}
}
Using Custom Exceptions in Service
@Service
public class ProductService {
@Transactional
public OrderDto createOrder(CreateOrderRequest request) {
for (OrderItemDto item : request.getItems()) {
Product product = productRepository.findById(item.getProductId())
.orElseThrow(() -> new ResourceNotFoundException("Product", item.getProductId()));
if (product.getStockQuantity() < item.getQuantity()) {
throw new InsufficientStockException(
product.getId(), item.getQuantity(), product.getStockQuantity());
}
product.setStockQuantity(product.getStockQuantity() - item.getQuantity());
productRepository.save(product);
}
// ... create order
}
}
Try-Catch Best Practices
// GOOD: Catch specific exceptions
try {
orderService.createOrder(request);
} catch (InsufficientStockException e) {
log.warn("Stock issue: {}", e.getMessage());
return ResponseEntity.badRequest().body(e.getMessage());
} catch (ResourceNotFoundException e) {
return ResponseEntity.notFound().build();
}
// BAD: Catching everything
try {
orderService.createOrder(request);
} catch (Exception e) { // Too broad!
return ResponseEntity.status(500).body("Error");
}
Exception Patterns
Custom Exceptions
public class NotFoundException extends RuntimeException {
public NotFoundException(String message) {
super(message);
}
}
Handling
- Catch specific exceptions
- Handle at appropriate layer
- Log with context
- Return meaningful errors
Best Practices
- Use unchecked exceptions for bugs
- Use checked exceptions for recoverable
- Don't catch and ignore
- Include correlation IDs
Key Points
- Understanding Exception Handling is essential for production systems
- Always consider scalability and maintainability
- Test thoroughly before deploying to production
- Monitor performance and set up alerting
Common Patterns
- Validation: Always validate input at the boundary
- Error Handling: Use structured error responses
- Logging: Log key events for debugging
- Testing: Unit, integration, and load tests
- Documentation: Keep docs updated with code changes
Practice Problems
Design and implement a solution for Exception Handling in a backend system. Consider scalability, error handling, and production readiness.
Solution
// Exception Handling implementation
// Key aspects: validation, error handling, logging, testing
public class ExceptionHandling {
// Production-ready implementation
}Identify and handle edge cases for Exception Handling. What happens under high load, with invalid input, or during failures?
Solution
// Edge case handling:
// 1. Null/empty input -> validation
// 2. High load -> rate limiting, queuing
// 3. Failures -> retries, circuit breaker
// 4. Concurrent access -> locks, idempotencyWrite a testing strategy for Exception Handling. Include unit tests, integration tests, and performance tests.
Solution
// Test plan:
// - Unit: 80% coverage target
// - Integration: API contracts
// - Performance: latency, throughput
// - Chaos: failure injectionQuiz
1. Why create custom exceptions instead of using generic ones?
2. What is wrong with catching "Exception" broadly?
3. What is the primary purpose of Exception Handling?
4. What is a common mistake when implementing Exception Handling?
Flashcards
Question
Why create custom exceptions?
Click to reveal answer
Answer
Provide specific error codes and clear intent for different failure types
Question
What should you never catch?
Click to reveal answer
Answer
Exception (too broad) — catch specific exception types instead
Question
What is Exception Handling?
Click to reveal answer
Answer
Exception Handling is a key concept in backend development.
Question
When to use Exception Handling?
Click to reveal answer
Answer
Use Exception Handling when building production systems that require reliability, scalability, and maintainability.
Question
Exception Handling best practices
Click to reveal answer
Answer
Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.
Revision Notes
Key Takeaways
- 1.Create custom exceptions for your domain (ResourceNotFoundException, etc.)
- 2.Extend RuntimeException for unchecked exceptions
- 3.Catch specific exceptions, never catch Exception broadly
- 4.Include error codes in exceptions for API responses
- 5.Log exceptions with context for debugging
Interview Tips
- •Know the difference between checked and unchecked exceptions
- •Be ready to design custom exception hierarchy
- •Understand when to catch vs propagate exceptions
Cheat Sheet
Exception Handling
- Custom Exceptions: ResourceNotFound, InsufficientStock, etc.
- Extend RuntimeException: Unchecked (no try-catch required)
- Error Codes: Include in exceptions for API responses
- Rule: Catch specific, never catch Exception broadly