Skip to content
intermediatePhase ·

Exception Handling

Handle exceptions gracefully in backend code.

40m
0 problems
Topic Progress0%

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

  1. Validation: Always validate input at the boundary
  2. Error Handling: Use structured error responses
  3. Logging: Log key events for debugging
  4. Testing: Unit, integration, and load tests
  5. Documentation: Keep docs updated with code changes

Practice Problems

0/3solved
Implement Exception Handling

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
}
Exception Handling Edge Cases

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, idempotency
Exception Handling Testing Strategy

Write 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 injection

Quiz

1. Why create custom exceptions instead of using generic ones?

Question 1 options

2. What is wrong with catching "Exception" broadly?

Question 2 options

3. What is the primary purpose of Exception Handling?

Question 3 options

4. What is a common mistake when implementing Exception Handling?

Question 4 options

Flashcards

Question

Why create custom exceptions?

Answer

Provide specific error codes and clear intent for different failure types

Question

What should you never catch?

Answer

Exception (too broad) — catch specific exception types instead

Question

What is Exception Handling?

Answer

Exception Handling is a key concept in backend development.

Question

When to use Exception Handling?

Answer

Use Exception Handling when building production systems that require reliability, scalability, and maintainability.

Question

Exception Handling best practices

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