← Python Coding Track

Module 08IntermediateWeeks 5–7

Error Handling & Debugging

01

Learning outcomes

  • Write resilient code that handles failures gracefully
02

Core concepts

try/except/finallyCommon exception typesDebugging techniques
03

Lessons

Module goal

Learner understands that failure is a normal part of programs running in the real world, and learns to anticipate, catch and handle errors gracefully instead of letting them crash the program.

Lesson 1 of 6 · lecture

Why programs fail — and why that's normal

Step 1 of 2

Every program written so far has assumed the world behaves predictably — the user types a number when asked for one, the file that's supposed to exist actually exists, the internet connection is stable. In reality none of that is guaranteed. Users mistype. Files get moved. Networks drop. Professional code anticipates that things will go wrong and handles it without crashing.

Teaching point

Up to now, an error has probably felt like “I did something wrong.” From here the mindset shifts: an error is information the program is giving you, and handling errors gracefully is itself a skill — arguably as important as writing the logic that works when everything goes right.

04

Guided labs

Lab — add error handling to the Contact Manager

  1. 1.Wrap the load-contacts logic so a missing file doesn't crash the program, and add a friendly message
  2. 2.When adding a contact, validate that the phone number contains only digits — if not, catch it and ask again instead of saving invalid data
  3. 3.When deleting a contact, handle the case where the entered name doesn't match any existing contact, rather than silently doing nothing
def load_contacts():
    contacts = []
    try:
        with open("contacts.txt", "r") as file:
            for line in file:
                name, phone, email = line.strip().split(",")
                contacts.append(Contact(name, phone, email))
    except FileNotFoundError:
        print("No existing contacts file found — starting fresh.")
    return contacts

def get_valid_phone():
    while True:
        phone = input("Phone: ")
        try:
            int(phone)  # confirms it's all digits
            return phone
        except ValueError:
            print("Phone number must contain digits only. Try again.")

def delete_contact(contacts, name_to_delete):
    matching = [c for c in contacts if c.name == name_to_delete]
    if not matching:
        print(f"No contact named '{name_to_delete}' was found.")
        return contacts
    return [c for c in contacts if c.name != name_to_delete]

Success criteria

The program no longer crashes on a missing contacts file, rejects a non-numeric phone number with a clear message and re-prompts, and gives useful feedback rather than failing silently when deleting a contact that doesn't exist.

05

Knowledge Check

Question 1 of 6

Why is an error in a program considered normal rather than a sign of bad coding?

06

What you read

  • Why programs fail
  • How to anticipate and catch errors
  • Reading tracebacks
07

What you understand

Key takeaways

  • Professional code anticipates failure
  • Debugging is a core skill, not a sign of weakness
08

Hands-on lab

Lab tasks

  1. 1.Add error handling to the Contact Manager (e.g., invalid input, missing file)
09

Knowledge check

  • Match exception types to scenarios

Write your answers in your own notes before moving on — explaining a concept in your own words is the fastest way to find the gaps.

10

Mark progress