PythonExceptions

Exceptions

An exception is Python’s way of signaling that something went wrong while a program was running. Instead of returning a special error code that a caller might forget to check, Python raises an object describing the problem and immediately stops normal execution, unwinding the call stack until something handles it — or the program crashes with a traceback. This is the language’s primary error-handling mechanism, and understanding it is essential for writing programs that fail predictably instead of silently producing wrong results.

Exceptions Are Objects

Every exception in Python is an instance of a class. When something goes wrong, Python creates an instance of the appropriate exception class, attaches a message and other data to it, and raises it. If nothing catches it, the interpreter prints a traceback and exits.

Python
# Dividing by zero raises an exception object
result = 10 / 0
Traceback (most recent call last):
  File "example.py", line 2, in <module>
    result = 10 / 0
ZeroDivisionError: division by zero
The Exception Hierarchy

Exception classes form a tree. At the root is BaseException, which almost nothing catches directly because it also covers things like SystemExit and KeyboardInterrupt — signals that a program is being deliberately stopped, not that something broke. Below that sits Exception, the ancestor of essentially every error you will actually want to catch or raise yourself. Below Exception come progressively more specific classes: LookupError is a parent of both IndexError and KeyError, ArithmeticError is a parent of ZeroDivisionError, and so on.

Python
BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- Exception
      +-- ArithmeticError
      |    +-- ZeroDivisionError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- ValueError
      +-- TypeError
      +-- AttributeError
      +-- FileNotFoundError (an OSError subclass)
      +-- ... many more
Note
This tree matters in practice because `except` clauses match a class *or any of its subclasses*. Catching `LookupError` will catch both `IndexError` and `KeyError`. Catching `Exception` will catch almost everything — which is usually too broad, since it also swallows programming mistakes you would rather see fail loudly.
Common Built-in Exceptions

You will encounter the same handful of exception types constantly. Knowing what typically triggers each one makes debugging much faster.

Exception

Typically raised when...

ValueError

A function receives an argument of the right type but an inappropriate value, e.g. int("abc").

TypeError

An operation or function is applied to an object of the wrong type, e.g. "2" + 2.

KeyError

A dictionary lookup uses a key that does not exist, e.g. {"a": 1}["b"].

IndexError

A sequence is indexed with a position outside its valid range, e.g. [1, 2][5].

ZeroDivisionError

The second operand of a division or modulo is zero, e.g. 1 / 0.

FileNotFoundError

Code tries to open a file that does not exist on disk, e.g. open("missing.txt").

AttributeError

Code accesses an attribute or method that does not exist on an object, e.g. "abc".push().

Reading a Traceback

A traceback looks intimidating at first, but it is just a record of the call stack at the moment the exception was raised, printed top to bottom in the order calls happened. The crucial habit is to read it bottom-up: the very last line names the exception type and the message, and the lines above it show the chain of function calls that led there, with the deepest call (where the error actually occurred) at the bottom of that chain.

Python
def get_price(catalog, name):
    return catalog[name]["price"]

def checkout(catalog, name):
    price = get_price(catalog, name)
    return price * 1.08

catalog = {"book": {"price": 12}}
checkout(catalog, "pen")
Traceback (most recent call last):
  File "shop.py", line 9, in <module>
    checkout(catalog, "pen")
  File "shop.py", line 5, in checkout
    price = get_price(catalog, name)
  File "shop.py", line 2, in get_price
    return catalog[name]["price"]
KeyError: 'pen'
  • Start at the bottom: KeyError: 'pen' tells you exactly what went wrong and with which value.

  • Move up one frame: catalog[name]["price"] in get_price is the exact line that failed.

  • Keep moving up to see why that line ran: checkout called it, and the top-level script called checkout("pen") with a name not in the catalog.

  • The fix belongs wherever the bad input first entered the program — here, validating name before calling checkout, or handling the missing key inside get_price.

Tip
In real projects, tracebacks are often much longer, spanning several files and library internals. Skim to the bottom for the exception type and message first, then scan upward for the first frame that belongs to *your* code (as opposed to a third-party library) — that is usually the most actionable line.