Chapter 9: Exception Handling in Python – Errors & Debugging

Previous Chapter Table of Contents Next Chapter

1. What is an Exception?

Definition: An exception is an error that occurs during program execution, disrupting normal flow.

Exceptions are raised when Python encounters unexpected situations.

Try-Catch Flow Diagram

Exception handling workflow

2. Common Exceptions

ZeroDivisionError

Division by zero

5 / 0

FileNotFoundError

Missing file

open("nonexistent.txt")

ValueError

Invalid conversion

int("abc")

IndexError

Invalid list index

lst = [1, 2]
lst[3]

KeyError

Missing dictionary key

d = {"a": 1}
d["b"]

TypeError

Operation on wrong type

"5" + 3

Exercise 1: Exception Identification

What exceptions will these raise?

  1. 10 / "two"
  2. [1, 2, 3][5]
  3. int("12.5")

3. Handling Exceptions

Basic try-except Block

try:
    # Risky code
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero!")

Always catch specific exceptions rather than using bare except:

Handling Multiple Exceptions

Separate Blocks

try:
    file = open("data.txt")
    num = int(file.read())
except FileNotFoundError:
    print("File missing")
except ValueError:
    print("Invalid number")

Single Block

try:
    # Risky code
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Exercise 2: Safe Division

Create a function that:

  1. Takes two numbers as input
  2. Returns their division
  3. Handles division by zero and type errors

4. Advanced Exception Handling

else and finally Clauses

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Division failed")
else:
    print(f"Result: {result}")  # Runs if no error
finally:
    print("Execution complete")  # Always runs

finally is ideal for cleanup code (like closing files) that must run regardless of errors.

Raising Exceptions

def validate_age(age):
    if age < 0:
        raise ValueError("Age cannot be negative")
    return True

try:
    validate_age(-5)
except ValueError as e:
    print(f"Error: {e}")

Exercise 3: Password Validator

Create a function that:

  1. Takes a password string
  2. Raises ValueError if length < 8
  3. Returns True if valid

5. Debugging Techniques

Using assert

def calculate_average(numbers):
    assert len(numbers) > 0, "List cannot be empty"
    return sum(numbers) / len(numbers)

Logging Exceptions

import logging

logging.basicConfig(filename='errors.log', level=logging.ERROR)

try:
    10 / 0
except ZeroDivisionError as e:
    logging.error(f"Division error: {e}")

Use logging for production code instead of print() statements.

Previous Chapter Next Chapter