MOD-25 · Sequence #25 · Practical Python

Python Try...Except & Error Handling

Robust software anticipates runtime failures. Python uses try, except, else, and finally blocks to handle exceptions gracefully. Catching specific exceptions rather than bare `except:` prevents silent bugs and preserves system interrupt signals.

Live Interactive Code Snippet (Python 3.12 CPython WASM) Open in Practice Mode →
try:
    x = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero!")
finally:
    print("Execution finalized")

Core Principles & Mental Models

1. The Complete Exception Handling Block

try, except, else, finally

  • `try`: Encloses code that might raise an exception.
  • `except SpecificError as e`: Catches and handles the specified exception.
  • `else`: Executes ONLY if the try block ran successfully WITHOUT any exceptions.
  • `finally`: Guaranteed to execute under all circumstances, even if an unhandled exception occurred or a return statement was encountered.
def read_number(prompt_val):
    try:
        num = float(prompt_val)
    except ValueError as e:
        print("Conversion failed:", e)
        return None
    else:
        print("Successfully parsed:", num)
        return num
    finally:
        print("Cleanup completed.")

read_number("42.5")
read_number("not_a_number")
💡 Key Takeaway: Use `else` for code that should only run on success, and `finally` for resource cleanup.

2. Raising Exceptions & Custom Exception Hierarchies

Inheriting from Exception (Never BaseException)

  • Use the `raise` keyword to signal error conditions: `raise ValueError("Invalid range")`.
  • Create custom domain exceptions by subclassing `Exception`.
  • Never subclass `BaseException` directly, as that bypasses standard exception catchers.
class InsufficientFundsError(Exception):
    """Raised when an account withdrawal exceeds available balance."""
    pass

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(f"Cannot withdraw ${amount} from ${balance}")
    return balance - amount

try:
    withdraw(50, 100)
except InsufficientFundsError as err:
    print("Caught business rule exception:", err)
💡 Key Takeaway: Custom exceptions provide clear, domain-specific error handling for your applications.

Interactive Walkthrough Examples

Catching Multiple Specific Exceptions (Basic)

Handling ZeroDivisionError and TypeError independently.

def calculate_metric(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return 0.0
    except TypeError as te:
        print(f"Type error encountered: {te}")
        return None

print("10 / 2 =", calculate_metric(10, 2))
print("10 / 0 =", calculate_metric(10, 0))
print("10 / 'str' =", calculate_metric(10, "str"))

Explanation: Different exceptions receive targeted recovery handling.

Common Misconceptions & Exam Traps

Common Pitfall: The Bare `except:` Anti-Pattern (Catching Everything)

Bare `except:` catches `BaseException`, masking KeyboardInterrupt and SystemExit, making programs unkillable.

Buggy Code
try:
    do_work()
except:  # CATCHES KeyboardInterrupt (Ctrl+C) and SystemExit!
    print("Something went wrong")  # User cannot terminate program!
Correct Solution
try:
    do_work()
except Exception as e:  # Catches standard errors, allows Ctrl+C exit
    print("Recovered from error:", e)

Exam Trap Note: Bare `except:` is flagged on exams as an anti-pattern. Always catch `Exception` or specific subclasses.

Conceptual Knowledge Self-Check Quiz

Q1: When does the `else` clause of a try/except/else/finally block execute?

  1. Always, after finally
  2. Only when an exception was caught in the except block
  3. Only when NO exception was raised in the try block
  4. When any exception is raised

The `else` block executes exclusively when the `try` block completes successfully without raising any exceptions.

Algorithmic Practice Challenges

Idiomatic Best Practices

  • ✅ Catch specific exceptions (e.g. `FileNotFoundError`, `KeyError`) instead of generic `Exception`.
  • ✅ Keep try blocks minimal, enclosing only the lines that could raise the target error.

All 26 Curriculum Modules