hayaliv

hayaliv / Hi! Python / Level 2

Exceptions

try/except lets a program handle a known error on purpose. Catch specific exceptions and raise your own when data is bad.

Hi! Python · Level 2: Level 2: Writing reliable code · Checked against the Python 3.12 documentation · Updated 2026-10-17

Think of it like this

An exception is like a smoke alarm in a kitchen. When something goes wrong, the alarm sounds and normal cooking stops. try/except is the cook who hears the alarm and deals with that exact problem.

Where the analogy stops being true. A smoke alarm only warns you, while Python stops the normal flow unless some except block handles the exception.

What to know

Example

import json

VALID = {"meeting_request", "not_interested"}

def check_label(label):
    if label not in VALID:
        raise ValueError(f"bad label: {label!r}")
    return label

for line in ['{"label": "meeting_request"}', '{"label": "spam"}', "not json", "{}"]:
    try:
        label = check_label(json.loads(line)["label"])
    except json.JSONDecodeError:
        print("bad json")
    except KeyError:
        print("missing label")
    except ValueError as err:
        print("invalid:", err)
    else:
        print("ok:", label)
    finally:
        print("done")

It prints:

ok: meeting_request
done
invalid: bad label: 'spam'
done
bad json
done
missing label
done

Predict, then check

1. What does this print?

try:
    print("a")
    x = {"k": 1}["z"]
    print("b")
except KeyError:
    print("c")
finally:
    print("d")
Show the answer
a
c
d

The KeyError skips the rest of the try block, so b never prints. The except block prints c, then finally prints d.

2. What does this print?

class EmptyReply(Exception):
    pass

def need_text(t):
    if not t:
        raise EmptyReply("no text")
    return t

try:
    need_text("")
except EmptyReply as err:
    print("caught", err)
Show the answer
caught no text

need_text raises EmptyReply because an empty string is false. The except block catches it and prints its message.

3. What does this print? (Look at the spelling inside try.)

def get_label():
    try:
        return lable
    except:
        return "fallback"

print(get_label())
Show the answer
fallback

The name lable is a typo, so Python raises NameError. The bare except hides it and returns the fallback, so the bug stays invisible.

Try it

Write parse_label(line). The line is a JSON text like '{"label": "meeting_request"}'. Return the label if it is in VALID. Return None if the text is not valid JSON. Raise ValueError if the label is not in VALID.

import json

VALID = {"meeting_request", "not_interested"}

def parse_label(line):
    return None
Show a solution
import json

VALID = {"meeting_request", "not_interested"}

def parse_label(line):
    try:
        data = json.loads(line)
    except json.JSONDecodeError:
        return None
    label = data["label"]
    if label not in VALID:
        raise ValueError(f"bad label: {label!r}")
    return label

Common mistake

A bare except: can hide a typo. In the third predict item, a misspelled name raised NameError and the bare except turned it into a quiet "fallback". Name the exception you expect instead.

In a small-language-model project

A real labelled dataset often has broken lines or labels you did not plan for. A good habit is to catch the specific errors, skip or report the bad row, and let unexpected errors stop the run so you notice them.

Sources

Each quote below appears word for word on the cited page of the official Python documentation (version 3.12).

Step through this lesson in the Hi! Python desktop

← Type hintsGenerators and lazy iteration →