Errors should never pass silently.
Unless explicitly silenced.
Tim Peters, Zen of Python
Error handling ensures that your program can respond gracefully to unexpected situations, such as invalid user input, missing files, or network timeouts. In Python, errors are communicated via exceptions. When an error arises, Python creates an exception object, interrupting the normal program flow. By handling exceptions proactively, you can prevent crashes and improve reliability.
Whether you’re developing simple scripts or large-scale applications, robust exception handling is important. It helps you troubleshoot issues faster and provides a better user experience by offering clear error messages or fallback actions instead of abrupt failures.
The try
and except
keywords are used to catch and
manage exceptions. If an error occurs within the try
block, Python checks the
matching except
block for that specific exception type, allowing the program
to continue.
try:
result = 10 / 0
except ZeroDivisionError:
result = "undefined"
print(result)
In this example, dividing by zero raises a ZeroDivisionError
. The
except
block catches it, assigns a fallback value, and prevents a crash.
A single try
block can have multiple except
blocks to handle different types of errors. This lets you tailor your response according to the specific
problem.
try:
my_list = [1, 2, 3]
result = my_list[5]
except IndexError:
result = "Index error"
except Exception as e:
result = str(e)
print(result)
In this code, a list
out-of-bounds access triggers IndexError
, handled separately from other generic exceptions.
Python provides optional else
and finally
blocks
to further refine error handling:
else
executes only if no exception occurs in the
try
block.
finally
always executes—making it ideal for cleanup tasks (like closing
file handles).
try:
result = 10 / 2
except ZeroDivisionError:
print("Divided by zero!")
else:
print("Division successful!")
finally:
print("This runs no matter what.")
You can use the raise
statement to manually throw an exception. This
is useful if you want to signal a specific error condition or enforce certain assumptions in your code.
def divide(a, b):
if b == 0:
raise ValueError("You can't divide by zero!")
return a / b
try:
result = divide(10, 0)
except ValueError as ve:
result = str(ve)
print(result)
By raising a ValueError
, you clearly highlight the problematic condition. This
approach makes the code’s intent more obvious to anyone reading or using this function.
For more complex applications, you may define your own exceptions that extend Python’s built-in
Exception
class. Custom exceptions help you handle domain-specific errors
more precisely and distinguish them from generic Python errors.
class NegativeValueError(Exception):
pass
def sqrt(value):
if value < 0:
raise NegativeValueError("Cannot compute the square root of a negative number!")
return value ** 0.5
try:
result = sqrt(-9)
except NegativeValueError as nve:
result = str(nve)
print(result)
Using custom exception names like OutOfStockError
can make error handling more
self-documenting in specialized domains.
When exceptions occur, it’s often helpful to log them for troubleshooting or auditing. Python’s
logging
module provides a consistent way to track errors (and other events)
in the console, files, or external logging services.
import logging
logging.basicConfig(level=logging.ERROR)
def divide(a, b):
try:
return a / b
except ZeroDivisionError as e:
logging.error("Attempted to divide by zero.", exc_info=True)
return "undefined"
result = divide(10, 0)
print(result)
The exc_info=True
parameter includes the traceback in your log, making it
easier to debug. You can adjust logging
to categorize different severity
levels (INFO
, WARNING
,
ERROR
, etc.).
Large Language Models (LLMs) can help you design robust error handling approaches. By outlining the kinds of problems you anticipate—like file system issues, network timeouts, or user input validation—you can request example code that demonstrates exception handling or Python best practices.
Example Prompt:Resulting AI-generated code:
def read_file(file_path):
try:
with open(file_path, 'r') as file:
content = file.read()
return content
except FileNotFoundError:
return "File not found."
except PermissionError:
return "Permission denied."
except Exception as e:
return f"An error occurred: {str(e)}"
file_content = read_file("example.txt")
print(file_content)
You can adapt AI-generated snippets to your specific needs—for instance, adding retries, re-raising exceptions in higher-level handlers, or combining file and network error management in a single function. Always test final solutions in real or simulated error scenarios before deployment.