Sharing notes from my ongoing learning journey — what I build, break and understand along the way.
Python Basics – Part 10: Error Handling and Exception Patterns
Error Handling and Exception Patterns in Python
In this part of the Python Basics series, we’ll explore error handling in Python — how to prevent your code from crashing, respond gracefully to unexpected situations, and keep your programs running smoothly.
We’ll look at try, except, else, and finally, discuss common error types, input validation, and best practices for writing robust code.
Understanding Exceptions
In Python, errors that occur during program execution are called exceptions.
For example:
print(int('22')) # Works fine
print(int('twenty')) # ValueError: invalid literal for int()
To prevent the program from crashing, you can wrap risky code inside a try block and handle errors using except:
try:
print(int('twenty'))
except ValueError:
print("The input was not an integer written in digits.")
print("Continuing program execution...")
Catching Specific Exceptions
It’s always better to handle only the errors you expect — not everything.
Avoid using a bare except: since it catches too much, including system interrupts.
try:
user_input = '0'
number = int(user_input)
print('Result of division:', 100 / number)
except ValueError:
print("Please enter a valid integer.")
except ZeroDivisionError:
print("Division by zero is not allowed.")
You can also handle multiple exception types together:
try:
risky_operation()
except (ValueError, ZeroDivisionError) as e:
print("Invalid input:", e)
Else and Finally Blocks
The else block runs only if no exception occurs,
and the finally block runs no matter what happens — ideal for cleanup tasks.
try:
from random import randint
user_input = ['0', '42'][randint(0, 1)]
number = int(user_input)
print("Result:", 100 / number)
except ZeroDivisionError:
print("Division by zero is not allowed.")
else:
print("Everything worked fine.")
finally:
print("Closing files or database connections...")
print("Program continues.")
This structure ensures that even if something fails, necessary cleanup still happens.
Exception Hierarchy and BaseException
Every exception in Python inherits from BaseException.
However, you should almost never catch BaseException, because it also includes system-level exceptions like KeyboardInterrupt and SystemExit.
Example (for learning purposes only):
try:
e1 = int('two') # ValueError
except BaseException as e:
print("Caught:", e)
print(type(e))
Best practice: Catch Exception or specific errors only.
try:
...
except Exception as e:
print("Something went wrong:", e)
Validating User Input
You can use both try/except or conditional checks (if/elif) for input validation.
The Pythonic approach is usually EAFP — “Easier to Ask for Forgiveness than Permission.”
Using try/except
while True:
try:
user_input = input("Please enter an integer greater than 0: ")
number = int(user_input)
result = 100 / number
except ValueError:
print("Please enter digits only.")
except ZeroDivisionError:
print("Please do not enter 0.")
else:
break
print("Program continues with 100 / input =", result)
Using if/elif
while True:
user_input = input("Please enter an integer greater than 0: ").strip()
if not user_input.lstrip('-').isdigit():
print("Digits only (optionally with a leading minus).")
continue
if user_input.startswith('0'):
print("Please do not start with 0.")
continue
number = int(user_input)
if number <= 0:
print("Please enter a number greater than 0.")
continue
break
Note: str.isdigit() works only for non-negative integers without a sign or decimal point.
Cleanup with finally and Context Managers
Instead of manually closing files in a finally block,
you can use Python’s with statement — a context manager that handles cleanup automatically.
try:
with open("data.txt") as f:
data = f.read()
print("File successfully read.")
except FileNotFoundError:
print("The file was not found.")
This is cleaner and less error-prone than manual open/close management.
Custom Exceptions and Raising Errors
You can define your own exception classes for specific application errors.
class InvalidUserInputError(Exception):
"""Custom exception for invalid input."""
pass
Then use it in your program:
user_input = -5
if user_input <= 0:
raise InvalidUserInputError("Input must be greater than zero.")
You can also re-raise exceptions when handling them:
try:
do_something()
except ValueError as e:
log_error(e)
raise # re-throw the same exception
Summary
In this part, you learned:
- How to handle errors gracefully using
try,except,else, andfinally. - Why specific exception handling is safer than generic ones.
- How to validate user input effectively.
- The use of
withblocks for automatic resource cleanup. - How to define and raise custom exceptions.
