Things go wrong in every real program — a user types text where a number was expected, a file doesn't exist, a network call times out. Python's try/except/else/finally block is how you catch those problems and keep the program running instead of crashing outright.

Catching Specific Exceptions

def safe_divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print("Error: cannot divide by zero")
        return None
    except TypeError:
        print("Error: both arguments must be numbers")
        return None
    else:
        print("Division succeeded")
        return result
    finally:
        print("Division attempt finished")


print(safe_divide(10, 2))
print("---")
print(safe_divide(10, 0))

Output:

Division succeeded
Division attempt finished
5.0
---
Error: cannot divide by zero
Division attempt finished
None

Each part of the block has a distinct job:

  • try — the code that might fail goes here.
  • except ZeroDivisionError / except TypeError — catches specific, named exception types. Catching specific exceptions (rather than a bare except:) matters because a bare except silently swallows every error, including genuine bugs you'd actually want to see.
  • else — runs only if the try block completed with no exception at all.
  • finally — always runs, whether an exception happened or not — the right place for cleanup code like closing a file or a network connection.

Raising Your Own Exception

def set_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative")
    print(f"Age set to {age}")


try:
    set_age(-5)
except ValueError as e:
    print(f"Caught an error: {e}")

Output:

Caught an error: Age cannot be negative

The as e part captures the exception object itself, so you can inspect its message (or any other data it carries) instead of just knowing that *something* went wrong. This same pattern — validate, then raise ValueError(...) — is how most of Python's own built-in functions signal bad input, which is why catching ValueError and TypeError specifically is so common in real code.