PythiloLesson 24 of 30 · progress kept in this browser

Raising your own exceptions

When a function cannot do its job, raise an exception rather than returning an odd value that the caller might not check. Pick the built-in type that fits: ValueError for a bad value, TypeError for a wrong type, KeyError for a missing key.

For errors that belong to your program, define your own class. It only needs a name and a parent:

class OutOfStock(Exception):
    pass

def take(stock, item):
    if stock.get(item, 0) == 0:
        raise OutOfStock(f"no {item} left")
    stock[item] -= 1

try:
    take({"tea": 0}, "tea")
except OutOfStock as error:
    print("sorry:", error)
  • except SomeError as error gives you the exception object, and str(error) is its message.
  • Inherit from ValueError or LookupError when your error is a special case of one, so handlers that already catch the parent keep working.
  • Write messages that say what went wrong and with which values.
Your task

Define InsufficientFunds as a subclass of ValueError. Write withdraw(balance, amount) returning the new balance, raising ValueError if amount is 0 or less, and InsufficientFunds with a message containing both numbers if amount is more than balance.