Exceptions Basics
Errors happen - files go missing, users enter invalid data, networks fail. Python's exception system lets you handle these gracefully instead of crashing. Understanding the difference between syntax errors and runtime exceptions, knowing the common exception types, and being able to read tracebacks are essential skills for every Python developer!
Syntax Errors vs Exceptions
Syntax errors occur when Python can't parse your code - it doesn't understand what you wrote. These must be fixed before the program can run. Exceptions occur during execution when something goes wrong at runtime. The code is valid Python, but the operation failed (like dividing by zero).
Click Run to execute your code
SyntaxError - Python can't understand your code (missing colons, unmatched brackets)- Detected before the program runs
- Cannot be caught with try/except
Exception - Code is valid but fails at runtime (divide by zero, file not found)- Detected during execution
- Can be caught and handled
Common Exception Types
Python has dozens of built-in exception types, each for specific error conditions. Knowing the
common ones helps you write better error handling and debug faster. The most frequent exceptions
you'll encounter are TypeError, ValueError, KeyError,
IndexError, and FileNotFoundError.
Click Run to execute your code
TypeError - Wrong type: "a" + 1, len(42)ValueError - Bad value: int("abc")IndexError - Bad index: list[999]KeyError - Missing key: dict["missing"]AttributeError - No attribute: "str".append()FileNotFoundError - File missing: open("nope.txt")
Exception Hierarchy
Python exceptions form a class hierarchy. All exceptions inherit from BaseException,
and most inherit from Exception. Understanding the hierarchy helps you catch related
exceptions together - catching LookupError catches both IndexError and
KeyError.
Click Run to execute your code
Exception or more specific
types. BaseException includes KeyboardInterrupt (Ctrl+C) and
SystemExit - catching these prevents users from stopping your program!
Reading Tracebacks
When an exception occurs, Python prints a traceback - a record of where the error happened and how the code got there. Read tracebacks from bottom to top: the error type is at the bottom, and the call stack shows how you got there.
Click Run to execute your code
1. Start at the BOTTOM - that's the error type and message
2. Read UP to see the call stack
3. Look for YOUR code (not library files)
4. The last line of your code before the error is usually the problem
5. Check variable values at that point
Common Mistakes
1. Catching too broadly
# Wrong - catches everything, hides bugs!
try:
result = do_something()
except: # Bare except - NEVER do this!
pass
# Also wrong - too broad
except Exception:
pass # Silently ignoring all errors
# Correct - catch specific exceptions
try:
result = do_something()
except ValueError:
print("Invalid value provided")
except FileNotFoundError:
print("File not found")
2. Ignoring the error message
# Wrong - throwing away useful info!
try:
data = json.loads(user_input)
except json.JSONDecodeError:
print("Invalid JSON") # What was wrong?
# Correct - use the error message
try:
data = json.loads(user_input)
except json.JSONDecodeError as e:
print(f"Invalid JSON at position {e.pos}: {e.msg}")
3. Catching exceptions in wrong order
# Wrong - specific exception never reached!
try:
open("file.txt")
except OSError:
print("OS error") # Catches FileNotFoundError too!
except FileNotFoundError:
print("File not found") # Never runs!
# Correct - specific exceptions first
try:
open("file.txt")
except FileNotFoundError:
print("File not found") # Runs for missing files
except OSError:
print("Other OS error") # Catches remaining OS errors
4. Using exceptions for flow control
# Wrong - using exceptions as if/else
try:
value = my_dict[key]
except KeyError:
value = default
# Correct - use dict.get() or 'in' check
value = my_dict.get(key, default)
# Or
if key in my_dict:
value = my_dict[key]
else:
value = default
5. Not reading the full traceback
# Error: AttributeError: 'NoneType' has no attribute 'strip'
# Many developers just see "AttributeError" and get confused
# The key info is 'NoneType' - something returned None!
# Check what could be None:
result = get_user_input() # This returned None!
cleaned = result.strip() # Can't call .strip() on None
# Fix: Check for None
result = get_user_input()
if result is not None:
cleaned = result.strip()
Exercise: Exception Identifier
Task: Create a function that identifies what type of exception a piece of code raises.
Requirements:
- Write a function that takes a callable and returns the exception name
- Return "No exception" if no error occurs
- Test with various error-causing operations
Click Run to execute your code
Show Solution
def identify_exception(func):
"""Run a function and return the exception type name."""
try:
func()
return "No exception"
except Exception as e:
return type(e).__name__
# Test cases
test_cases = [
("Division by zero", lambda: 1 / 0),
("String + int", lambda: "a" + 1),
("List index", lambda: [1, 2, 3][10]),
("Dict key", lambda: {}["missing"]),
("Int parse", lambda: int("hello")),
("File open", lambda: open("nonexistent.txt")),
("No error", lambda: 1 + 1),
]
print("=== Exception Identifier ===\n")
for name, func in test_cases:
result = identify_exception(func)
print(f"{name:20} -> {result}")
# Expected output:
# Division by zero -> ZeroDivisionError
# String + int -> TypeError
# List index -> IndexError
# Dict key -> KeyError
# Int parse -> ValueError
# File open -> FileNotFoundError
# No error -> No exception
Summary
- Syntax errors: Detected before running, can't be caught
- Exceptions: Runtime errors, can be caught with try/except
- TypeError: Wrong type for operation
- ValueError: Right type, invalid value
- KeyError: Dictionary key not found
- IndexError: List index out of range
- FileNotFoundError: File doesn't exist
- Hierarchy: Exceptions inherit from parent classes
- Tracebacks: Read bottom-to-top for error details
- Best practice: Catch specific exceptions, not broad ones
What's Next?
Now that you understand what exceptions are, let's learn how to handle them
with try/except. You'll learn to catch exceptions gracefully, handle multiple
exception types, and keep your programs running even when errors occur!
Enjoying these tutorials?