Article 9: Error Handling and Logging
Introduction
Exception Handling Fundamentals
The Basics
# Basic try-except
try:
result = risky_operation()
except SomeException as e:
handle_error(e)Exception Hierarchy
Catching Specific Exceptions
# Bad: Catching everything hides bugs
try:
process_data(data)
except: # Never do this!
pass
# Bad: Too broad
try:
process_data(data)
except Exception: # Still too broad
log.error("Something went wrong")
# Good: Catch specific exceptions
try:
user = fetch_user(user_id)
process_order(user, order_data)
except UserNotFoundError:
return {"error": "User not found"}, 404
except InvalidOrderError as e:
return {"error": str(e)}, 400
except DatabaseConnectionError:
log.error("Database connection failed")
return {"error": "Service temporarily unavailable"}, 503Multiple Exception Types
Custom Exceptions
Creating Custom Exceptions
Using Custom Exceptions
Exception Context
Error Handling Patterns
The Result Pattern
Fail Fast
Graceful Degradation
Retry Pattern
Logging
Basic Logging Setup
Structured Logging
Logging Best Practices
Logging Configuration
Context Managers for Logging
Debugging Strategies
Using the Debugger
Debugger Commands
Debug Logging
Assertions for Debugging
Practical Exercise
Exercise 1: Implement Error Handling
Exercise 2: Add Logging
Error Handling Checklist
Key Takeaways
What's Next?
Last updated