Errors

try, except, else, finally, raise, and reading a traceback.

When Python cannot continue, it raises an exception. try / except handles it. Read the last line of a traceback first, then the line number above it.

Goal

Catch a specific error, use else/finally, and raise your own.

Read a traceback

scores = [98, 91]
print(scores[5])

IndexError: list index out of range — the operation, not Python, is wrong.

Catch one type

raw = "n/a"
try:
    n = int(raw)
except ValueError:
    n = None
print(n)

Catch the error you expect. Bare except: hides bugs.

else and finally

def parse_int(raw):
    try:
        n = int(raw)
    except ValueError:
        print("not an int")
        return None
    else:
        print("parsed")
        return n
    finally:
        print("always runs")

print(parse_int("42"))
print("---")
print(parse_int("x"))

else runs if nothing was raised. finally runs either way (cleanup).

Several excepts

def lookup(row, key):
    try:
        return row[key]
    except KeyError:
        return "missing key"
    except TypeError:
        return "not a mapping"

print(lookup({"name": "Ada"}, "name"))
print(lookup({"name": "Ada"}, "city"))
print(lookup(["Ada"], "name"))

raise

def band(score):
    if score < 0 or score > 100:
        raise ValueError("score must be 0..100")
    return "A" if score >= 90 else "other"

print(band(95))
try:
    print(band(140))
except ValueError as err:
    print("caught:", err)
Tip

Handle errors at the edge (reading a file, parsing text). Let unexpected bugs surface so you can fix them.