Python Exception Handling: try-except Blocks and Custom Errors
Production applications encounter unexpected situations, from unreadable files to dropped network connections. Without robust error handling, unhandled exceptions cause applications to crash instantly. Python exception handling enables software to catch runtime errors gracefully, execute fallback routines, and maintain operational stability.
This guide covers try-except blocks, handling multiple exception types, using else and finally clauses, and defining custom exceptions.
Key Takeaways
- Wrap code prone to runtime errors inside
tryblocks and catch exceptions withexceptclauses. - Always catch specific exceptions (e.g.,
ValueError,FileNotFoundError) rather than bareexcept:statements. - The
elseblock executes only when no exceptions occur; thefinallyblock runs unconditionally for cleanup tasks. - Custom exceptions are created by inheriting from Python’s built-in
Exceptionclass.
1. The Structure of Exception Handling
Catch errors using specific exception types to prevent your program from halting unexpectedly.
Python
def execute_division(numerator, denominator):
try:
result = numerator / denominator
except ZeroDivisionError as error:
print(f"[ERROR] Invalid operation: {error}")
return None
else:
print("[SUCCESS] Calculation completed with no errors.")
return result
finally:
print("[SYSTEM] Cleanup routine executed.")
# Safe execution
output = execute_division(100, 0)
2. Handling Multiple Exception Types
An operation can fail for multiple reasons. Chain multiple except blocks or pass a tuple of exceptions to handle distinct failure modes separately.
Python
import json
def parse_configuration(file_path):
try:
with open(file_path, "r") as file:
data = json.load(file)
return data["database_port"]
except FileNotFoundError:
print(f"[FAIL] Configuration file '{file_path}' missing.")
except json.JSONDecodeError:
print(f"[FAIL] File '{file_path}' contains malformed JSON.")
except KeyError:
print("[FAIL] Required key 'database_port' absent from JSON.")
3. Creating Custom Exceptions
Define domain-specific custom exceptions to communicate business logic errors clearly across large codebases.
Python
class InsufficientPrivilegesError(Exception):
"""Raised when a user attempts an unauthorized administrative action."""
def __init__(self, user_role, required_role="Admin"):
self.user_role = user_role
self.required_role = required_role
super().__init__(f"Role '{user_role}' lacks required permissions ('{required_role}').")
def AccessControlModule(user):
if user["role"] != "Admin":
raise InsufficientPrivilegesError(user_role=user["role"])
# Triggering custom error handling
try:
AccessControlModule({"username": "dev_user", "role": "Guest"})
except InsufficientPrivilegesError as err:
print(f"Access Denied: {err}")
4. Exception Hierarchy Reference
| Class | Purpose | Typical Trigger |
BaseException | Root class for all exceptions (avoid catching directly) | System exit, keyboard interrupt |
Exception | Base class for user-defined and standard errors | Standard runtime errors |
ValueError | Correct data type passed, but invalid value provided | int("invalid_string") |
TypeError | Incompatible data type passed to function or operator | "text" + 42 |
Conclusion
Mastering Python exception handling separates fragile scripts from resilient software. Catching specific errors, executing cleanup via finally, and defining custom error classes guarantees that your application recovers predictably from unexpected failures.

