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 anyexceptblock 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-inExceptionclass 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 bareexceptclause. It catches all exceptions, includingSystemExitandKeyboardInterrupt, which can prevent the user from interrupting the program and make debugging difficult. Always specify the exception types you intend to catch.