Unit 7 • Lesson 8

The try and except Blocks

Overview

You can use try and except blocks to prevent crashes and respond to problems gracefully. This section shows how to catch specific exceptions, print helpful error messages, and continue program execution safely, building fault-tolerant applications.

Beginner 25–30 min

What You Will Learn in This Lesson

By the end of this lesson, you will know:

  • try and except: Use these blocks to catch and handle exceptions.
  • Handling specific exceptions: Catch only the errors you expect.
  • Error messages: Print helpful messages when errors occur.
  • else and finally: Use optional blocks for additional control.
  • Best practices: Write robust code that handles errors gracefully.

The Problem: Programs Crashing

When an exception occurs, your program stops running. This is called "crashing." But what if you want your program to continue even when something goes wrong?

Problem: Program Crashes on Error
file = open("data.txt", "r")
content = file.read()
file.close()
# If file doesn't exist, program crashes here!
print("Program continues...")  # Never reached

The issue: If the file doesn't exist, Python raises a FileNotFoundError and stops. The rest of your program never runs.

Solution: try and except

The try and except blocks let you catch exceptions and handle them gracefully, so your program can continue running.

Basic Syntax
try:
    # Code that might cause an error
    file = open("data.txt", "r")
    content = file.read()
    file.close()
except FileNotFoundError:
    # What to do if the error occurs
    print("File not found!")
    
print("Program continues...")  # This runs even if error occurred

How It Works

  1. Python tries to execute the code in the try block
  2. If an exception occurs, Python jumps to the except block
  3. After handling the error, the program continues normally

Catching Specific Exceptions

You can catch specific types of exceptions by naming them after except:

Catching FileNotFoundError
try:
    file = open("data.txt", "r")
    content = file.read()
    file.close()
except FileNotFoundError:
    print("The file doesn't exist!")
except PermissionError:
    print("You don't have permission to read this file!")
Catching Multiple Exceptions
try:
    number = int(input("Enter a number: "))
    result = 10 / number
except ValueError:
    print("That's not a valid number!")
except ZeroDivisionError:
    print("You can't divide by zero!")

Catching All Exceptions

You can catch any exception using except without specifying a type, but this is generally not recommended:

Catching Any Exception
try:
    file = open("data.txt", "r")
    content = file.read()
    file.close()
except:
    print("Something went wrong!")
    # This catches ALL exceptions - use carefully!

Best Practice

Always catch specific exceptions when possible. Catching all exceptions can hide bugs and make debugging harder.

Getting Error Information

You can access the error message using as:

Accessing Error Details
try:
    file = open("data.txt", "r")
    content = file.read()
    file.close()
except FileNotFoundError as e:
    print(f"Error: {e}")
    # Prints: Error: [Errno 2] No such file or directory

The else Block

The else block runs only if no exception occurred:

Using else
try:
    file = open("data.txt", "r")
    content = file.read()
    file.close()
except FileNotFoundError:
    print("File not found!")
else:
    print("File read successfully!")
    # This only runs if no exception occurred

The finally Block

The finally block always runs, whether an exception occurred or not. It's useful for cleanup:

Using finally
try:
    file = open("data.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("File not found!")
finally:
    print("Cleanup: This always runs")
    # Useful for closing files, cleaning up resources, etc.

Note

With the with statement, you don't need finally for file closing, but it's still useful for other cleanup tasks.

Combining with File Operations

Here's how to use try and except with file operations:

Safe File Reading
try:
    with open("data.txt", "r") as file:
        content = file.read()
        print(content)
except FileNotFoundError:
    print("The file 'data.txt' was not found.")
except PermissionError:
    print("You don't have permission to read this file.")
except Exception as e:
    print(f"An unexpected error occurred: {e}")
Safe File Writing
def safe_write_file(filename, data):
    """Safely write data to a file"""
    try:
        with open(filename, "w") as file:
            file.write(data)
        print(f"Successfully wrote to {filename}")
        return True
    except PermissionError:
        print(f"Permission denied: Cannot write to {filename}")
        return False
    except OSError as e:
        print(f"OS error: {e}")
        return False
    except Exception as e:
        print(f"Unexpected error: {e}")
        return False

# Usage
success = safe_write_file("output.txt", "Hello, World!")
if success:
    print("File operation completed successfully")
Complete File Operation with All Blocks
def read_file_complete(filename):
    """Demonstrates try, except, else, and finally"""
    file = None
    try:
        file = open(filename, "r")
        content = file.read()
    except FileNotFoundError:
        print(f"Error: File '{filename}' not found")
        return None
    except PermissionError:
        print(f"Error: Permission denied for '{filename}'")
        return None
    else:
        print("File read successfully!")
        return content
    finally:
        if file:
            file.close()
        print("Cleanup: File handle closed")

# Note: Using 'with' statement is better, but this shows finally

try/except/else/finally Flow

Understanding the execution flow:

  1. try: Code that might raise an exception
  2. except: Runs if an exception occurs
  3. else: Runs only if NO exception occurred
  4. finally: Always runs, regardless of exceptions

Remember: With the with statement, you rarely need finally for file closing, but it's useful for other cleanup tasks.

Nested try/except Blocks

You can nest try/except blocks for more granular error handling:

Nested Exception Handling
def process_multiple_files(filenames):
    """Process multiple files with individual error handling"""
    results = []
    
    for filename in filenames:
        try:
            with open(filename, "r") as file:
                content = file.read()
                # Process content
                processed = content.upper()
                results.append(processed)
        except FileNotFoundError:
            print(f"Warning: {filename} not found, skipping...")
            continue  # Skip to next file
        except PermissionError:
            print(f"Warning: Cannot read {filename}, skipping...")
            continue
        except Exception as e:
            print(f"Unexpected error with {filename}: {e}")
            continue
    
    return results

# Usage
files = ["file1.txt", "file2.txt", "file3.txt"]
results = process_multiple_files(files)
print(f"Processed {len(results)} files successfully")

Error Handling Strategy

When processing multiple items (like files), handle errors individually so one failure doesn't stop the entire process. This makes your program more resilient!

Practice: Handling Exceptions

Try It Yourself

Try using try and except to handle errors gracefully:

Click "Run Code" to see your output here

What happened? The code tried to convert "abc" to an integer, which caused a ValueError. The except block caught it and printed a message, then the program continued.

Summary

In this lesson, you learned:

  • try/except: Catch and handle exceptions to prevent crashes
  • Specific exceptions: Catch only the exceptions you expect
  • Error messages: Use as to access error details
  • else: Runs only if no exception occurred
  • finally: Always runs, useful for cleanup
  • Best practice: Combine with with statement for file operations

Remember

Always handle exceptions that you expect might occur. This makes your programs more robust and user-friendly!

End-of-Lesson Exercises

Think about these questions to reinforce what you've learned:

Exercise 1: Why Try/Except?

Why is it important to use try/except blocks when working with files? Give an example.

Exercise 2: Handling Errors

Write pseudocode for safely reading a file that might not exist, and printing a helpful message if it doesn't.