PythonMastery

Custom exception in Python

Define your own exception class, InsufficientFundsError, that carries the balance and the amount. Raise it, catch it and use its fields.

A custom exception is a class that inherits from Exception. Its name says exactly what went wrong, and it can carry extra data that the code catching it can use.

The program

python
class InsufficientFundsError(Exception):
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        self.shortfall = amount - balance
        super().__init__(
            f"cannot withdraw {amount:.2f}, balance is {balance:.2f}"
        )


def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(balance, amount)
    return balance - amount


balance = 120.00

for amount in [50.00, 200.00]:
    try:
        balance = withdraw(balance, amount)
        print(f"Withdrew {amount:.2f}. New balance: {balance:.2f}")
    except InsufficientFundsError as error:
        print("Refused:", error)
        print(f"You need {error.shortfall:.2f} more.")
output
Withdrew 50.00. New balance: 70.00
Refused: cannot withdraw 200.00, balance is 70.00
You need 130.00 more.

How it works

A family of errors

Give your exceptions a shared base class. Then the caller can catch one specific error, or all of them at once:

python
class BankError(Exception):
    pass


class InsufficientFundsError(BankError):
    pass


class AccountLockedError(BankError):
    pass


for error_type in [InsufficientFundsError, AccountLockedError]:
    try:
        raise error_type("example")
    except BankError as error:
        print(f"Caught {type(error).__name__}")
output
Caught InsufficientFundsError
Caught AccountLockedError

except BankError catches both, because each one is a BankError. The bank account class is a full example where an error like this fits.

Related programs: Raise an exception.

Learn the idea: Exceptions: Patterns Beyond the Basics, Object-Oriented Programming