Chapter 10

Error Handling & Debugging

Handle errors gracefully and debug like a pro!

🛡️ Understanding Errors

Errors are a normal part of programming! Instead of letting your program crash, you can handle errors gracefully and provide helpful feedback to users.

Think of error handling like a safety net - it catches problems before they break your program!

Why Error Handling Matters

Imagine you're building a calculator app. Without error handling:

  • User enters "abc" instead of a number → Program crashes
  • User tries to divide by zero → Program crashes
  • File doesn't exist → Program crashes

With error handling, you can catch these problems and show friendly messages instead!

Two Types of Errors

There are two main types of errors in Python:

1️⃣ Syntax Errors

What: Code that doesn't follow Python's rules

When: Detected before code runs

Examples: Missing colons, typos, wrong indentation

Fix: Correct the code

2️⃣ Exceptions

What: Errors during program execution

When: Occur while code is running

Examples: Division by zero, file not found

Fix: Use try/except blocks

Example 1: Program Without Error Handling (Bad!)

Output will appear here...

Example 2: With Error Handling (Good!)

Output will appear here...

Example 3: Real-World Scenario

Output will appear here...

🔍 What Happens When An Error Occurs?

When Python encounters an error, here's what happens step-by-step:

  1. Error Detected: Python finds a problem (e.g., can't convert "abc" to int)
  2. Exception Created: Python creates an exception object with error details
  3. Looking for Handler: Python searches for try/except blocks
  4. Two Outcomes:
    • ✅ Handler found → Runs the except block, program continues
    • ❌ No handler → Program crashes with traceback

Think of it like: Throwing a ball (exception) and someone catches it (except block) vs. nobody catches it (crash)!

🎯 Key Takeaway

Error handling = making your programs robust and user-friendly. Instead of crashing, your program handles problems gracefully and keeps running!

🎯 try/except Blocks - Your Safety Net

The try/except block lets you "try" code that might fail and "catch" any errors that occur.

Think of it as: Try something risky, but if it fails, except (handle) the problem!

The Basic Structure

try:
    # Code that might cause an error
    risky_operation()
except ErrorType:
    # Code to handle the error
    handle_error()

🔍 How try/except Works (Step-by-Step)

  1. Enter try block: Python starts executing code inside try
  2. If success: Code runs normally, skip the except block
  3. If error occurs: Stop immediately, jump to matching except block
  4. Handle error: Execute code in except block
  5. Continue: Program continues after the try/except

Example 1: Simple Division

Output will appear here...

Example 2: Division by Zero

Output will appear here...

Example 3: Safe Division Function

Output will appear here...

Example 4: Converting String to Number

Output will appear here...

Example 5: Converting Invalid String

Output will appear here...

Example 6: Safe Number Converter Function

Output will appear here...

💡 Best Practices

  • Be specific: Catch specific exceptions (ValueError, not just Exception)
  • Keep try blocks small: Only include code that might fail
  • Provide helpful messages: Tell users what went wrong
  • Have a recovery plan: What should happen after catching an error?

📋 Common Error Types - Know Your Enemies!

Python has many built-in exception types. Here are the most common ones you'll encounter:

The "Big 7" Exceptions Every Beginner Should Know

ValueError

When: Right type, wrong value

Example: int("abc")

TypeError

When: Wrong type for operation

Example: "hi" + 5

ZeroDivisionError

When: Divide by zero

Example: 10 / 0

IndexError

When: Invalid list/string index

Example: list[999]

KeyError

When: Dictionary key missing

Example: dict["missing"]

FileNotFoundError

When: File doesn't exist

Example: open("nope.txt")

AttributeError

When: Attribute doesn't exist

Example: list.invalid()

Let's See Each One in Action!

Example 1: ValueError

Scenario: Converting invalid string to number

Output will appear here...

Example 2: TypeError

Scenario: Mixing incompatible types

Output will appear here...

Example 3: ZeroDivisionError

Scenario: Division by zero

Output will appear here...

Example 4: IndexError

Scenario: Accessing invalid list index

Output will appear here...

Example 5: KeyError

Scenario: Accessing missing dictionary key

Output will appear here...

Example 6: AttributeError

Scenario: Calling non-existent method

Output will appear here...

Example 7: Multiple Errors in One Program

Scenario: Handling different errors appropriately

Output will appear here...

🔍 How to Remember These Exceptions

  • ValueError: Value is wrong (wrong VALUE)
  • TypeError: Type is wrong (wrong TYPE)
  • ZeroDivisionError: Self-explanatory - dividing by ZERO
  • IndexError: Index out of bounds (bad INDEX)
  • KeyError: Dictionary key not found (missing KEY)
  • FileNotFoundError: File doesn't exist (FILE NOT FOUND)
  • AttributeError: Method/property doesn't exist (missing ATTRIBUTE)

🔄 Handling Multiple Exceptions

You can handle different types of errors with separate except blocks!

Think of it as: Different problems need different solutions!

Part 1: Creating the Function

First, let's create a function that can handle multiple types of errors:

Output will appear here...

Part 2: Testing Valid Input

Let's test with valid input first:

Output will appear here...

Part 3: Testing ValueError (Invalid Number)

What happens when we pass text instead of a number?

Output will appear here...

Part 4: Testing ZeroDivisionError

What happens when we try to divide by zero?

Output will appear here...

Part 5: Testing IndexError

What happens when we use an invalid index?

Output will appear here...

🔍 How Python Checks Multiple except Blocks

Python checks except blocks in order:

  1. Error occurs in try block
  2. Python checks first except - does it match? If yes, run it and stop
  3. If no, check next except block
  4. Repeat until a match is found
  5. If no match found, error crashes the program

Order matters! Put specific exceptions before general ones.

Catching Multiple Exceptions in One Block

You can also catch multiple exception types with a single except block using a tuple:

Output will appear here...

🎯 Key Takeaways

  • Multiple except blocks = handle different errors differently
  • Python checks except blocks in order from top to bottom
  • Always return a value (even if it's None) to avoid confusion
  • Use tuple syntax to catch multiple exceptions with same handling

🔚 The finally Clause

finally runs no matter what - whether an exception occurred or not. Perfect for cleanup tasks like closing files!

Output will appear here...

🚨 Raising Exceptions

You can raise your own exceptions using the raise keyword. This is useful for validation!

Output will appear here...

🐛 Debugging Tips

Essential Debugging Techniques

  • Print statements: Add print() to see variable values
  • type(): Check what type a variable is
  • Read the traceback: Error messages tell you exactly what went wrong
  • Test small pieces: Test functions individually
  • Use meaningful names: Makes bugs easier to spot

Debugging Example

Output will appear here...

📺 Video Resources

Python Exception Handling

Corey Schafer

Complete guide to try/except, raising exceptions, and best practices.

Watch Video

Python Debugging

Tech With Tim

Learn effective debugging techniques and tools.

Watch Video

🤖 AI Learning Prompts

Understanding Error Handling

Help me master Python error handling:

1. Explain try/except/finally with examples
2. When should I catch specific vs general exceptions?
3. Show me 10 real-world error handling scenarios
4. How do I write custom error messages?
5. Give me practice problems for exception handling

Include best practices!

Debugging Skills

Teach me effective debugging:

1. What are the best debugging strategies?
2. How do I read Python tracebacks?
3. Show me debugging techniques for different error types
4. Give me exercises where I fix broken code
5. How do professionals debug complex programs?

Make it practical!

✏️ Practice Exercises

Challenge: Input Validator

Output will appear here...

Challenge 2: File Handler with Error Handling

Difficulty: Medium | Time: 15 minutes

Task: Create a safe file reader that handles missing files and permission errors.

Output will appear here...

Challenge 3: List Index Error Handler

Difficulty: Easy | Time: 10 minutes

Task: Create a safe list accessor that handles index errors gracefully.

Output will appear here...

Challenge 4: Dictionary Key Error Handler

Difficulty: Medium | Time: 15 minutes

Task: Create a safe dictionary accessor with multiple error checks.

Output will appear here...

Challenge 5: Custom Exception Practice

Difficulty: Hard | Time: 20 minutes

Task: Create custom exceptions for a banking system with validation.

Output will appear here...

🎯 Knowledge Check

Question 1: What happens if an exception occurs and there's no try/except block?

Question 2: When does the finally block execute?

Question 3: Which exception is raised when converting "abc" to an integer?

Question 4: What does the raise keyword do?

Question 5: What's the best practice for catching exceptions?

🎓 Course Complete!

Congratulations! You've completed all Python fundamentals! You now have a solid foundation in Python programming. Keep practicing and building projects to reinforce your skills!