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.
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?
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.
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
- Python tries to execute the code in the
tryblock - If an exception occurs, Python jumps to the
exceptblock - After handling the error, the program continues normally
Catching Specific Exceptions
You can catch specific types of exceptions by naming them after except:
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!")
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:
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:
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:
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:
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:
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}")
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")
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:
- try: Code that might raise an exception
- except: Runs if an exception occurs
- else: Runs only if NO exception occurred
- 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:
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 YourselfTry using try and except to handle errors gracefully:
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
asto access error details - else: Runs only if no exception occurred
- finally: Always runs, useful for cleanup
- Best practice: Combine with
withstatement 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.