Try/except basics

try / except

Wrap risky code in a try block, and handle the failure in an except block:

try:
    result = 10 / 0
except ZeroDivisionError:
    result = None
    print("can't divide by zero")

If nothing goes wrong, the except block never runs. If a ZeroDivisionError is raised anywhere inside the try block, execution jumps straight to the matching except and continues from there — the program doesn't crash.

Catching a specific type

Always name the exception type you expect. except ZeroDivisionError: only catches that one type — anything else still propagates and crashes, which is what you want: an unexpected bug shouldn't be silently swallowed.

try:
    age = int(user_input)
except ValueError:
    print("that's not a number")

Getting the exception object

Use as e to inspect the exception itself — its message is available via str(e):

try:
    age = int(user_input)
except ValueError as e:
    print(f"invalid input: {e}")

Raising your own

You're not limited to catching exceptions Python raises for you — use raise to signal a problem yourself:

def withdraw(balance, amount):
    if amount > balance:
        raise ValueError("insufficient funds")
    return balance - amount

Calling code can then catch it exactly like a built-in exception:

try:
    balance = withdraw(balance, 500)
except ValueError as e:
    print(f"withdrawal failed: {e}")

That's the core pattern you'll use throughout this section: some code that might fail, a try around it, and an except naming exactly what you're prepared to handle.