LambdaLabTM
Computer Science · Class 12 · Exception Handling
ExceptionsHierarchy⏱️ 12 min read

The Exception Tree

ZeroDivisionError is not just a message. It is a name — and every one of those names sits somewhere in a family tree with BaseException at the top. This is not trivia. The tree is exactly what decides which except block catches which error.

1The tree, with the parts you will actually meet

Python has around sixty built-in exceptions. Here are the ones worth knowing, in their proper places. Indentation shows descent — each one is a kind of the thing above it:

BaseExceptionthe root — everything is one of these
SystemExitthe program was asked to quit
KeyboardInterruptyou pressed Ctrl+C
GeneratorExitinternal housekeeping
Exceptioneverything you would ever want to catch
ArithmeticError
ZeroDivisionError10 / 0
OverflowError
LookupError
IndexErrormarks[5] on a list of 3
KeyErrora key the dictionary does not have
OSError
FileNotFoundErrorno such file
ValueErrorint('twelve')
TypeError'2' + 2
NameErrora name you never created
AttributeError
ImportError
ModuleNotFoundErrorimport nosuchmodule
SyntaxErrorin the tree, but see below
IndentationError
Note
Two rows are worth a second look. SystemExit and KeyboardInterrupt hang off BaseException rather than Exception, and that placement is deliberate: they are not really errors, they are requests to stop. Keeping them out from under Exception means an ordinary handler cannot accidentally swallow your Ctrl+C.

2Why a family tree matters at all

Because catching a parent catches all its children. That single rule is the whole reason the shape of the tree is worth knowing:

parent_catches_child.py
try:
    x = 10 / 0
except ArithmeticError:
    print('caught — ZeroDivisionError is a kind of ArithmeticError')
Output
caught — ZeroDivisionError is a kind of ArithmeticError

The error raised was a ZeroDivisionError. The handler names ArithmeticError, which is its parent, and it caught it anyway. Walk further up and the same thing keeps working — except Exception would have caught it too, and so would except BaseException.

The chain for a division by zero
ZeroDivisionError → ArithmeticError → Exception → BaseException

Any of those four names in an except will catch it. The further up you go, the more other things you catch along with it — which is the subject of the “Catching the Right One” lesson, and the reason the first name is almost always the right choice.

3Exception: the root of everything you care about

Nearly every exception a program of yours can raise is somewhere under Exception. That makes it the widest net worth having, and the reason you will sometimes see except Exception written as a last resort at the very outside of a large program.

It is also the reason except Exception is such a bad habit anywhere else. It catches the error you were expecting and every error you were not, and reports them all the same way. There is a whole lesson on that two pages from here.

4Why SyntaxError is in the tree and still uncatchable

SyntaxError sits under Exception like the others, which looks as though you ought to be able to catch it. In your own file, you cannot — and the last lesson explained why. Python reads the whole file before running any of it, so a syntax error in this file is raised before your try exists.

Key Takeaway
Being in the tree and being catchable are different questions. SyntaxError is a proper exception class — it is just that the mistake happens too early in the life of your program for any handler in that program to be running yet.

5The names worth memorising

ExceptionRaised whenExample
ZeroDivisionErroryou divide by zero10 / 0
ValueErrorthe type is right, the value is notint('twelve')
TypeErrorthe type itself is wrong'2' + 2
IndexErrorthe position does not existmarks[5] on 3 items
KeyErrorthe key does not existrecord['Sara']
NameErrorthe name was never createdprint(totl)
FileNotFoundErrorthe file is not thereopening a missing file

You do not have to learn the whole tree. You have to learn these seven names and the one rule that a parent catches its children — that is everything the chapter needs from you.

6Recap

BaseException is the root

Every exception in Python descends from it. Nothing sits outside the tree.

Exception holds everything you catch

SystemExit, KeyboardInterrupt and GeneratorExit deliberately sit beside it, not under it — they are requests to stop, not errors.

A parent catches its children

except ArithmeticError catches ZeroDivisionError. This one rule is why the shape of the tree matters.

Further up catches more

ZeroDivisionError → ArithmeticError → Exception → BaseException. Each step widens the net, usually further than you meant.

In the tree ≠ catchable

SyntaxError is a real exception class, but a syntax error in your file happens before your try block exists.

✍️ Now write these yourself
  1. 1

    Catch a ZeroDivisionError using except ArithmeticError and check that it works.

    Hint · A parent catches its children. That is the whole rule.

  2. 2

    Do the same with except Exception, then with except IndexError.

    Hint · The first catches it; the second does not, because IndexError is on a different branch.

  3. 3

    Write down the chain from KeyError up to BaseException.

    Hint · KeyError → LookupError → Exception → BaseException. Four names, same shape as the division one.

Quick Check

Which of these catches a ZeroDivisionError?

Quick Check

Why do SystemExit and KeyboardInterrupt sit under BaseException rather than Exception?

Quick Check

SyntaxError is in the tree. Can you catch one in your own file?