All 15 Exceptions questions
More in Exceptions
Advertisement
Java › Exceptions

How would you design a custom exception hierarchy for an application, deciding when to create new exception classes versus reusing existing ones, and what fields/context should a well-designed custom exception carry?

Advanced

Answer

A well-designed custom exception hierarchy typically has a common base exception for the application/domain (like OrderException extends RuntimeException), with specific subtypes for genuinely distinct failure categories callers might need to handle differently (InsufficientInventoryException, PaymentDeclinedException) -- new exception classes are warranted when calling code needs to programmatically distinguish and react differently to a specific failure category (catching the specific subtype), while reusing a generic exception (or a shared parent type) is appropriate when the specific failure reason doesn't actually change how calling code should react; a well-designed custom exception should carry sufficient contextual data (not just a message string) for both logging/debugging purposes and, where relevant, for calling code to programmatically inspect and react to the specific failure details.
public class InsufficientInventoryException extends OrderException {
    private final String productId;
    private final int requested, available;

    public InsufficientInventoryException(String productId, int requested, int available) {
        super(String.format("Insufficient inventory for %s: requested %d, available %d", productId, requested, available));
        this.productId = productId;
        this.requested = requested;
        this.available = available;
    }
    // getters let calling code programmatically inspect the specific shortfall, not just read a message string
}
Real-world example An order-processing system's InsufficientInventoryException carries structured fields (productId, requested, available quantities) rather than just an error message string, letting the calling UI code programmatically extract and display exactly how many units are actually available to the customer, rather than needing to parse an unstructured error message.

Common follow-ups: When does creating a new specific exception subtype provide genuine value versus becoming unnecessary proliferation?;How would you design this hierarchy to work well with a global exception handler mapping exceptions to appropriate HTTP status codes?