Python tutorials > Error Handling > Exceptions > How to handle multiple exceptions?
How to handle multiple exceptions?
Basic `try...except` block
try...except
block. The code that potentially raises an exception is placed inside the try
block. If an exception of the specified type (e.g., ZeroDivisionError
) occurs, the corresponding except
block is executed.
try:
# Code that might raise an exception
result = 10 / 0 # This will raise a ZeroDivisionError
except ZeroDivisionError:
print("Cannot divide by zero!")
Handling multiple exceptions with separate `except` blocks
except
blocks for each type. This allows you to tailor the error handling logic specifically to each exception. In this example, we catch both ValueError
(if the user enters non-integer input) and ZeroDivisionError
.
try:
num = int(input("Enter a number: "))
result = 10 / num
print(f"Result: {result}")
except ValueError:
print("Invalid input: Please enter a valid integer.")
except ZeroDivisionError:
print("Cannot divide by zero!")
Handling multiple exceptions with a single `except` block (using a tuple)
except
block. This can simplify your code if the response to different exceptions is the same. Note that the same code will run for both ValueError
and ZeroDivisionError
in this example.
try:
num = int(input("Enter a number: "))
result = 10 / num
print(f"Result: {result}")
except (ValueError, ZeroDivisionError):
print("Invalid input or division by zero!")
Using `except Exception` to catch all exceptions
except Exception as e
to catch any type of exception. The Exception
class is the base class for all built-in, non-system-exiting exceptions. Using as e
allows you to access the exception object itself, which can be useful for logging the error or displaying more detailed information to the user. However, catching all exceptions in this way is generally discouraged as it can mask underlying issues and make debugging harder. It's often better to catch specific exceptions whenever possible.
try:
# Some code that might raise any exception
result = 10 / int(input("Enter a number: "))
print(f"Result: {result}")
except Exception as e:
print(f"An error occurred: {type(e).__name__} - {e}")
The `else` Clause
else
clause in a try...except
block is executed if no exceptions are raised in the try
block. This is a good place to put code that should only run if the potentially problematic code executes successfully.
try:
num = int(input("Enter a number: "))
result = 10 / num
except ValueError:
print("Invalid input: Please enter a valid integer.")
except ZeroDivisionError:
print("Cannot divide by zero!")
else:
print(f"Result: {result}")
The `finally` Clause
finally
clause is always executed, regardless of whether an exception was raised or not. This is commonly used for cleanup operations, such as closing files or releasing resources. It guarantees that these operations will be performed even if an exception occurs within the try
block or one of the except
blocks. The code checks if the file object `f` exists in the local scope (using `if 'f' in locals()`) and if it has a `close` method (using `hasattr(f, 'close')`) before attempting to close it. This prevents errors if the file wasn't successfully opened in the first place.
try:
f = open("my_file.txt", "r")
data = f.read()
# Process the data
except FileNotFoundError:
print("File not found!")
finally:
if 'f' in locals() and hasattr(f, 'close'):
f.close() # Ensure the file is closed, even if an exception occurs
Concepts Behind the Snippet
try...except...else...finally
block is the primary mechanism for exception handling in Python. The goal is to anticipate possible errors, handle them appropriately, and ensure that critical resources are released, regardless of errors.
Real-Life Use Case Section
requests.exceptions.RequestException
), JSON parsing errors (json.JSONDecodeError
), or other unexpected issues. Proper error handling ensures that the application doesn't crash and displays a user-friendly error message, or tries to retry after a delay. In database interactions, catching exceptions like sqlalchemy.exc.OperationalError
(database connection issues) or sqlalchemy.exc.IntegrityError
(unique constraint violations) is essential to maintain data integrity and application stability.
Best Practices
Exception
unless absolutely necessary. Catching specific exceptions allows you to handle each error appropriately and prevents masking underlying issues.logging
module to log exceptions along with relevant context (e.g., timestamps, user IDs, input data). This helps in debugging and identifying recurring issues.except
clause (without specifying an exception type) catches SystemExit
and KeyboardInterrupt
exceptions, potentially preventing the user from interrupting the program.finally
clause to ensure resources are released, regardless of whether an exception occurred.
Interview Tip
try...except...else...finally
block. Be able to explain the trade-offs between catching specific exceptions and catching broad exceptions. Also, be prepared to discuss the importance of logging exceptions and using the finally
clause for resource cleanup. Be ready to provide real-world examples of exception handling scenarios. For instance, describe how you would handle potential errors when reading data from a file, making API calls, or interacting with a database.
When to Use Them
except
blocks when you have different error handling strategies for each exception type. Use tuple-based except
when the error handling logic is the same for a group of exceptions. Use except Exception as e
with caution, primarily for logging or displaying generic error messages, and ideally only at the top level of your application. Use the else
clause for code that depends on the successful execution of the try
block. Always use the finally
clause for essential cleanup operations.
Memory Footprint
Alternatives
try...except
blocks, other approaches to error handling include:
These alternatives aren't as robust or flexible as exception handling for dealing with unexpected errors.if
statements to validate input data or check for potential errors before they occur. This can sometimes be more efficient than using exception handling.
Pros
Cons
FAQ
-
What happens if an exception is raised but not caught?
If an exception is raised and not caught by anyexcept
block in the current scope, it propagates up the call stack. If it reaches the top level of the program without being caught, the program will terminate and display an error message including the traceback. -
Can I create my own custom exception types?
Yes, you can create custom exception types by defining a class that inherits from the built-inException
class or one of its subclasses. This allows you to represent application-specific errors more accurately. -
Is it a good practice to use a bare except clause?
No, it's generally not a good practice to use a bareexcept
clause. It catches all exceptions, includingSystemExit
andKeyboardInterrupt
, which can prevent the user from interrupting the program and make debugging difficult. Always specify the exception types you intend to catch.