PythiloLesson 12 of 15 · progress kept in this browser

Exceptions instead of error codes

Returning -1, None or "error" when something fails makes every caller check the result, and a forgotten check lets the failure flow on as if it were data: -1 happily joins a sum.

Raise an exception instead. Callers that can handle the failure catch it, everyone else lets it propagate, and nobody can mistake it for a result.

class OutOfStock(Exception):
    pass

def take(have, qty):
    if qty > have:
        message = f"want {qty}, have {have}"
        raise OutOfStock(message)
    return have - qty

try:
    take(2, 5)
except OutOfStock as error:
    print("cannot ship:", error)

Give a module its own exception classes when callers need to tell its failures apart, with one base class so that they can also catch them all at once. Put the details in the message, and in attributes when callers need the values.

Your task

Define BankError(Exception) with subclasses InvalidAmount and InsufficientFunds. withdraw(balance, amount) raises InvalidAmount for an amount of 0 or less and InsufficientFunds for an amount over the balance, instead of returning -1 and -2. InsufficientFunds keeps balance and amount as attributes.