java-crear-excepciones-propias-custom

How to Create Custom Exceptions in Java

  • 3 min

A custom exception is a type of exception that expresses a specific failure in the application’s domain.

Java has many ready-to-use exceptions, such as IOException, NullPointerException, or IllegalArgumentException.

But what if you are programming a banking system and a user tries to withdraw more money than they have? You could throw an IllegalArgumentException, yes. But that is too generic. It doesn’t explain why the operation failed in your business context.

The ideal would be to throw an InsufficientBalanceException.

Creating your own exceptions allows your code to speak the language of your business, making errors easier to understand and manage.

How to Create an Exception

Technically, creating an exception is ridiculously easy. You just need to create a class and make it inherit from one of the parent classes.

// Option A: Checked Exception (Forces handling)
public class InsufficientBalanceException extends Exception {

    public InsufficientBalanceException(String message) {
        super(message); // Pass the message to the parent (Exception)
    }
}
Copied!

That’s it. Now you can use it in your code:

throw new InsufficientBalanceException("You are short by 50 euros");
Copied!

Choosing Between Exception and RuntimeException

When creating an exception, you must decide whether the caller will be forced to declare or catch it:

Extending Exception (checked)

You choose this option when the error is a foreseeable business event from which we can recover. You want to force the programmer using your method to think about what to do if this happens.

  • Example: InsufficientBalanceException.

  • Why: It is very likely that a user will try to withdraw too much money. If it happens, we want to force the graphical interface to display a nice message: “Insufficient balance, try a smaller amount.”

Extending RuntimeException (unchecked)

You choose this option when the error indicates a bug, incorrect API usage, or an unrecoverable state. You do not want to force a try-catch because if this happens, the programmer should fix their code, not catch the error.

  • Example: AccountBlockedException (if it’s a fatal state) or NegativeAmountException.

  • Why: If someone tries to deposit -100 euros, it’s a logic failure. We don’t want a try-catch; we want the programmer to fix that call.

Complete Example: The ATM

Let’s implement the bank case using a checked exception because we want to handle it.

Step 1: The Exception We can add extra attributes to provide more information (e.g., how much money is missing).

public class InsufficientBalanceException extends Exception {
    private double missingAmount;

    public InsufficientBalanceException(String message, double missing) {
        super(message);
        this.missingAmount = missing;
    }

    public double getMissingAmount() {
        return missingAmount;
    }
}
Copied!

Step 2: The Business Class

public class BankAccount {
    private double balance = 100.0;

    // We WARN with 'throws' that this method can fail
    public void withdraw(double amount) throws InsufficientBalanceException {
        if (amount > balance) {
            double missing = amount - balance;
            // We THROW the error
            throw new InsufficientBalanceException("There isn't enough money", missing);
        }
        balance -= amount;
        System.out.println("Successful withdrawal. Remaining: " + balance);
    }
}
Copied!

Step 3: The Usage (Handling)

public static void main(String[] args) {
    BankAccount account = new BankAccount();

    try {
        account.withdraw(500.0); // This will fail
    } catch (InsufficientBalanceException e) {
        // We handle the business error elegantly
        System.out.println("Error: " + e.getMessage());
        System.out.println("You are short by: " + e.getMissingAmount() + " euros.");
    }
}
Copied!