Exception Handling: Keep Programs Safe and User-Friendly
Introduction
In this chapter, you will learn exception handling in Python, a key skill for writing robust programs. Exceptions happen when something unexpected occurs during execution, such as invalid input or missing files. By handling exceptions properly, your program can fail gracefully instead of crashing.
Prerequisites
- Python
3.10+installed - Basic understanding of functions, conditions, loops, and input/output
- Ability to run
.pyfiles in terminal or IDE
What Is an Exception
An exception is an error raised while the program is running.
Common examples:
ValueError(invalid value conversion)ZeroDivisionError(division by zero)FileNotFoundError(file does not exist)KeyError(missing dictionary key)
Without handling, exceptions stop the program immediately.
1) Basic try / except
Use try for risky code and except for fallback handling.
try:
# Convert user input to integer
number = int(input("Enter an integer: "))
print(f"You entered: {number}")
except ValueError:
# Handle invalid integer input
print("Invalid input. Please enter a valid integer.")This prevents user mistakes from crashing the script.
2) Handle Multiple Exception Types
You can catch different exceptions separately.
try:
# Read two numbers
a = int(input("Enter a: "))
b = int(input("Enter b: "))
# Risky operation
print(a / b)
except ValueError:
print("Input must be integers.")
except ZeroDivisionError:
print("Division by zero is not allowed.")This gives users clearer feedback.
3) else and finally
elseruns when no exception occursfinallyalways runs (with or without exception)
try:
# Try risky operation
x = int(input("Enter a number: "))
except ValueError:
print("Invalid input.")
else:
# Run only when try succeeds
print(f"Valid number: {x}")
finally:
# Always run
print("Execution finished.")finally is useful for cleanup tasks (closing files, releasing resources).
Tip
Best Practice
Catch specific exceptions whenever possible.
Avoid broad except Exception unless you have a clear reason.
4) Raise Exceptions Manually
Use raise to trigger exceptions when business rules are violated.
def set_age(age):
# Validate age range
if age < 0 or age > 130:
raise ValueError("Age must be between 0 and 130.")
print(f"Age set to {age}")
try:
set_age(200)
except ValueError as e:
print(e)This helps enforce input contracts in your functions.
5) Exception Object (as e)
Capture exception details for logs or user feedback.
try:
value = int("abc")
except ValueError as e:
print(f"Caught error: {e}")This is useful for debugging and error reporting.
6) Real Mini Example: Score Input Guard
This script safely collects scores and prevents invalid data.
# Create score list
scores = []
# Collect 3 scores safely
for i in range(1, 4):
while True:
try:
# Read one score
score = float(input(f"Enter score #{i}: "))
# Validate score range
if score < 0 or score > 100:
raise ValueError("Score must be between 0 and 100.")
# Save valid score
scores.append(score)
break
except ValueError as e:
print(f"Invalid score: {e}")
# Print final result
print("Valid scores:", scores)
print(f"Average: {sum(scores) / len(scores):.2f}")This pattern is common in form validation and data-entry systems.
Warning
Do not silently ignore errors with empty except blocks.
Hidden errors make debugging much harder.
Common Beginner Mistakes
Mistake 1: Catching Too Broadly
Using except: without type can hide important bugs.
Mistake 2: Mixing Too Much Logic Inside try
Keep try blocks focused on truly risky statements.
Mistake 3: Forgetting to Validate After Conversion
Successful conversion does not guarantee business-valid values.
Surprise Practice Challenge
Build a "Safe Calculator":
- Ask user for two numbers and one operator (
+,-,*,/) - Handle invalid number input
- Handle division by zero
- Handle unsupported operators with
raise ValueError - Keep calculator running until user types
exit
If you finish this, you can write beginner-level resilient console applications.
FAQ
Why not just let program crash on errors?
Graceful handling improves user experience and prevents data loss in real applications.
Should I always use finally?
Use finally when cleanup is required. It is not mandatory for every try block.
Is except Exception as e always bad?
Not always, but use it carefully. Prefer specific exception types first.
How do I know which exception type to catch?
Read error messages, Python docs, and test edge cases intentionally.