08.1 - Exceptions & Try/Except/Finally
Theory 25 min Intermediate
What is an Exception?
An exception is an error that occurs during execution. If not handled, it crashes the program.
# This crashes with ZeroDivisionError
result = 10 / 0
# This crashes with ValueError
int("hello")
# This crashes with FileNotFoundError
open("missing.txt")
Exception Hierarchy
BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception
├── ArithmeticError
│ ├── ZeroDivisionError
│ └── OverflowError
├── AttributeError
├── FileNotFoundError (IOError)
├── ImportError
├── IndexError
├── KeyError
├── MemoryError
├── NameError
├── RuntimeError
├── StopIteration
├── TypeError
├── ValueError
└── OSError
try / except / else / finally
try:
# Code that might raise an exception
result = int(input("Enter a number: "))
answer = 10 / result
except ValueError as e:
# Handles ValueError (e.g., non-numeric input)
print(f"Invalid number: {e}")
except ZeroDivisionError:
# Handles division by zero
print("Cannot divide by zero!")
except (TypeError, OverflowError) as e:
# Handle multiple exception types together
print(f"Type/overflow error: {e}")
except Exception as e:
# Catch-all for any other exception
print(f"Unexpected error: {type(e).__name__}: {e}")
else:
# Runs ONLY if NO exception was raised
print(f"Result: {answer}")
finally:
# ALWAYS runs, even if exception occurred
print("Done — cleaning up")
Raising Exceptions
def divide(a, b):
if not isinstance(a, (int, float)):
raise TypeError(f"Expected number, got {type(a).__name__}")
if b == 0:
raise ZeroDivisionError("Cannot divide by zero")
return a / b
# Re-raise with context
def process_data(data):
try:
result = parse(data)
except ParseError as e:
raise ValueError(f"Invalid data format: {data}") from e
# The original exception is chained as __cause__
# Raise without context (suppress original)
raise ValueError("Invalid data") from None
Common Built-in Exceptions
| Exception | When |
|---|---|
ValueError | Wrong value type or range |
TypeError | Wrong type |
KeyError | Dict key not found |
IndexError | List index out of range |
AttributeError | Object has no such attribute |
FileNotFoundError | File doesn't exist |
PermissionError | No permission to access file |
ZeroDivisionError | Divided by zero |
ImportError | Module not found |
RuntimeError | Generic runtime error |
NotImplementedError | Abstract method not implemented |
StopIteration | Iterator exhausted |
LBYL vs EAFP
| Style | Description | Python preferred |
|---|---|---|
| LBYL | Look Before You Leap — check before acting | C/Java style |
| EAFP | Easier to Ask Forgiveness than Permission | Python style |
# LBYL — check first
if "key" in d:
value = d["key"]
# EAFP — try and handle
try:
value = d["key"]
except KeyError:
value = default
Python strongly favors EAFP — it's more readable and avoids race conditions.
Key Vocabulary
| Term | Definition |
|---|---|
| Exception | An error that occurs during program execution |
try | Block where exceptions might occur |
except | Block that handles a specific exception |
else | Block that runs only if no exception occurred |
finally | Block that always runs, for cleanup |
raise | Explicitly raise an exception |
| Exception chaining | raise X from Y — links exceptions |
| EAFP | Pythonic style: try first, handle exceptions |
Summary
- Use
try/exceptto handle exceptions gracefully elseruns only on success;finallyalways runs- Catch specific exception types — avoid bare
except:(catches everything includingKeyboardInterrupt) raise ExceptionType("message")raises exceptions with contextraise X from Ychains exceptions preserving the original cause- Python style is EAFP: try the operation, handle exceptions — don't check first
📄️ 08.1 - Exceptions
Handle Python exceptions gracefully with try/except/else/finally, understand the exception hierarchy, and raise exceptions correctly
📄️ 08.2 - Custom Exceptions & Logging
Create custom exception hierarchies and replace print() debugging with Python's professional logging module
📄️ 08.3 - Debugging
Debug Python programs using breakpoints, pdb, VS Code debugger, assertions, and traceback analysis
📄️ Lab - Module 08
Build a CLI contact manager with custom exceptions, professional logging, and input validation
📄️ Quiz - Module 08
30 questions on exceptions, try/except, custom errors, logging, and debugging