7. Python Error Handling & Logging#
1. try-except-finally - Overview#
- Used to handle runtime errors gracefully and ensure cleanup code always runs
- Most robust and maintainable solution for unexpected errors in data pipelines
2. Execution Order - No Exception:#
try → finally
# except block is SKIPPED if no exception occurs
3. Execution Order - Exception Occurs:#
4. finally Block:#
- ALWAYS runs regardless of whether exception occurred or not
- Used for: closing files, DB connections, releasing resources
try:
result = risky_operation()
except ValueError as e:
print(f"Error: {e}")
finally:
cleanup() # ALWAYS runs ✅
5. else Block:#
- Runs only when NO exception occurs
try:
result = risky_operation()
except ValueError:
print("Error")
else:
print("Success") # only if no exception
finally:
cleanup() # always
6. Specific Exception Types:#
- Always use specific exception types over generic ones
except ValueError # wrong value type
except FileNotFoundError # file doesn't exist
except KeyError # dictionary key missing
except TypeError # wrong data type
except ZeroDivisionError # division by zero
except Exception # catch-all (use sparingly)
7. Generic Exception:#
- Catches everything - use only as last resort
- Hides bugs by catching unexpected errors silently
- ✅ Always prefer specific exceptions
8. Common Wrong Answers:#
- ❌
try-catch-finally → Java/JavaScript syntax, NOT Python - ❌
if-else-finally → not valid Python - ❌
try only → no cleanup, no error handling - ❌ Using only generic
try-except → too broad, misses specific handling
9. logging Module:#
- Better than
print() for production code - Records errors with timestamps, severity levels
import logging
logging.debug("Debug info") # development details
logging.info("Pipeline started") # general info
logging.warning("Missing data") # something unexpected
logging.error("API call failed") # serious problem
logging.critical("DB crashed") # system failure
Log Levels (low → high):#
DEBUG < INFO < WARNING < ERROR < CRITICAL
10. Error Handling in Data Pipelines:#
# ✅ Exam-relevant pattern
try:
df = pd.read_csv('data.csv')
except FileNotFoundError:
logging.error("Data file missing")
except pd.errors.EmptyDataError:
logging.error("File is empty")
finally:
logging.info("Pipeline step complete")