Python for AIPython 3.10+ · Pydantic 2.12
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
33 small wins to finish your pathNext lesson

try and except: handling errors

One bad answer stopped the loop in lesson 17. try and except let a program notice an error, deal with it, and carry on with the next ticket.

Examplefrom lesson 17
import json

def ask_model(ticket_text):
    text = ticket_text.lower()
    if "charged" in text or "refund" in text:
        return '{"category": "billing", "priority": 4}'
    if "parcel" in text or "arrived" in text:
        return '{"category": "shipping", "priority": 3}'
    return "I am not sure how to sort this one."

with open("tickets.json") as f:
    tickets = json.load(f)
Example
answer = ask_model("How do I change my password?")

try:
    data = json.loads(answer)
except json.JSONDecodeError:
    data = {"category": "other", "priority": 1}

print(data)

Python runs the try block. If json.loads raises a JSONDecodeError, it jumps to the except block instead of stopping, and the program continues after it.

Name the error you expect. except json.JSONDecodeError handles unreadable JSON and nothing else. A typo in a variable name inside the try still stops the program, which is what you want: that is a bug to fix, not an answer to work around.

The loop that no longer breaks

Example
unsorted = []
for ticket in tickets:
    try:
        data = json.loads(ask_model(ticket["text"]))
    except json.JSONDecodeError:
        unsorted.append(ticket["id"])
        continue
    print(ticket["id"], data["category"])

print("Needs a person:", unsorted)

continue skips the rest of this pass through the loop and moves to the next ticket. All five are handled, and the one the model could not sort is kept for a person instead of being lost.

Raising your own error

Sometimes the value parses but is still wrong. raise stops with an error you choose, and a message saying why.

Example
def check_priority(priority):
    if priority < 1 or priority > 5:
        raise ValueError(f"priority must be 1 to 5, got {priority}")
    return priority

print(check_priority(4))
print(check_priority(9))
Example
try:
    check_priority(9)
except ValueError as error:
    print("rejected:", error)

as error gives the caught error a name, and printing it shows its message. Checking every field by hand like this gets long; lesson 24 hands the job to Pydantic.

Try it yourself
  • Remove continue and read the error that follows.
  • Put data = json.loads(answr), with the typo, inside the first try. Does the except catch it?
  • Call check_priority(0) inside the try.

Slow is fine. Stopping is the only problem.