How to Catch Multiple Exceptions in Python?

As a Python developer with over a decade of experience, I came across various scenarios where I needed to handle errors. Today, I’m going to walk you through one of Python’s most powerful error-handling features: catching multiple exceptions. Let us learn various methods to catch multiple exceptions in Python with suitable examples.

Python Multiple Exceptions

The foundation of exception handling in Python is the try-except block. Here’s a quick refresher:

try:
    # Code that might raise an exception
    value = 10 / 0
except ZeroDivisionError:
    # Code to handle the exception
    print("You can't divide by zero!")

Output:

You can't divide by zero!

You can see the output in the screenshot below.

python catch multiple exceptions

Read How to Save a Python Dictionary as a JSON File?

Method 1: Use Multiple except Blocks

The most simple approach is to use multiple except blocks, each handling a specific exception type:

try:
    file = open("important_data.txt", "r")
    number = int(file.readline())
    result = 100 / number
    file.close()
except FileNotFoundError:
    print("The file doesn't exist. Creating a new one...")
    file = open("important_data.txt", "w")
    file.write("10")
    file.close()
except ValueError:
    print("The file doesn't contain a valid number.")
except ZeroDivisionError:
    print("The file contains zero, which causes a division error.")

Output:

The file doesn't exist. Creating a new one...

You can see the output in the screenshot below.

python handling multiple exceptions

This method provides clear organization and allows you to implement specific handling for each exception type.

Check out How to Write a Dictionary to a File in Python?

Method 2: Catch Multiple Exceptions in a Single except Block

Sometimes, you may want to handle different exceptions in the same way. Python allows you to catch multiple exceptions in a single except block:

import json 
default_settings = {"option": "default_value"} 

try:
    with open("config.txt") as file:
        config = json.loads(file.read()) 
        settings = config["settings"] 
except (FileNotFoundError, json.JSONDecodeError, KeyError) as error:
    print(f"Configuration error: {error}")
    print("Using default configuration instead.")
    settings = default_settings 

print("Settings:", settings)

Output:

Configuration error: [Errno 2] No such file or directory: 'config.txt'
Using default configuration instead.
Settings: {'option': 'default_value'}

You can see the output in the screenshot below.

python multiple exceptions

This approach is cleaner when you want to handle different exceptions with the same response.

Read How to Download Files from URLs Using Python?

Method 3: Use Exception Hierarchies

Python’s exceptions follow an inheritance hierarchy. You can catch a parent exception to handle all its children:

try:
    # Some database operations
    db = connect_to_database("customers.db")
    records = db.query("SELECT * FROM customers WHERE state = 'California'")
    process_records(records)
except OSError as e:
    # This will catch FileNotFoundError, ConnectionError, and other OS-related errors
    logger.error(f"Database operation failed: {e}")
    send_alert_to_admin("Dave Johnson", "Database error")
except Exception as e:
    # Catch any other exceptions
    logger.critical(f"Unexpected error: {e}")
    send_alert_to_admin("Dave Johnson", "Critical system error")

Read How to Copy Files to Another Directory in Python?

Method 4: Use else and finally Clauses

For more advanced exception handling, combine try-except with else and finally:

try:
    user_data = get_user_from_database("jsmith@example.com")
    user_preferences = parse_preferences(user_data)
except UserNotFoundError:
    print("User not found. Please sign up first.")
    redirect_to_signup()
except PreferenceParsingError:
    print("Error in your preference settings. Using defaults.")
    user_preferences = default_preferences
else:
    # This executes if no exceptions were raised
    print(f"Welcome back, {user_data.name}!")
    apply_user_preferences(user_preferences)
finally:
    # This always executes, regardless of exceptions
    close_database_connection()
    log_access_attempt("jsmith@example.com")

The else clause runs only if no exceptions occur, while the finally clause always runs, making it perfect for cleanup operations.

Check out How to Open a File in Python?

Method 5: Use Exception Groups

If you’re using Python 3.11 or newer, you can use the new exception groups feature to handle multiple exceptions with more flexibility:

try:
    # Complex operation that might raise multiple exceptions
    result = perform_complex_operation()
except* ValueError as exc_group:
    # Handle all ValueError exceptions
    for exc in exc_group.exceptions:
        print(f"Value error: {exc}")
except* (TypeError, KeyError) as exc_group:
    # Handle both TypeError and KeyError exceptions
    for exc in exc_group.exceptions:
        print(f"Data structure error: {exc}")

This newer syntax is particularly useful when handling exceptions from concurrent code.

Read How to Check if a File Exists in Python?

Best Practices for Exception Handling in Python

After years of debugging Python applications for clients ranging from startups in Silicon Valley to established enterprises in Chicago, I’ve developed these best practices:

PracticeDescriptionExample
Be specificCatch specific exceptions rather than generic onesUse FileNotFoundError instead of just Exception
Don’t silence exceptionsAlways log or handle exceptions meaningfullyLog detailed error information for debugging
Keep try blocks smallOnly wrap code that might actually raise exceptionsDon’t put your entire program in one try block
Use context managersUse with statements for resources that need cleanupwith open('file.txt') as f:
Add custom exceptionsCreate custom exception classes for your application’s specific errorsclass ConfigurationError(Exception): pass

Check out How to Print the Contents of a File in Python?

Common Python Exceptions

Here are some of the most common exceptions you’ll encounter:

  • ValueError: Raised when a function receives an argument of the correct type but with an inappropriate value
  • TypeError: Raised when an operation or function is applied to an object of inappropriate type
  • FileNotFoundError: Raised when trying to access a file that doesn’t exist
  • KeyError: Raised when a dictionary key is not found
  • IndexError: Raised when a sequence index is out of range
  • AttributeError: Raised when an attribute reference or assignment fails
  • ImportError: Raised when an import statement fails
  • ZeroDivisionError: Raised when division or modulo by zero is performed

Example: Data Processing

Let me show you a real-world example from a data processing application I built for a client in Boston:

def process_customer_data(filename):
    customers = []
    try:
        with open(filename, 'r') as file:
            for line in file:
                try:
                    name, age, email = line.strip().split(',')
                    age = int(age)
                    if not validate_email(email):
                        raise ValueError(f"Invalid email: {email}")
                    customers.append({"name": name, "age": age, "email": email})
                except ValueError as e:
                    logger.warning(f"Skipping invalid record: {line.strip()}. Error: {e}")
                except Exception as e:
                    logger.error(f"Unexpected error processing record: {line.strip()}. Error: {e}")
    except FileNotFoundError:
        logger.error(f"Customer data file not found: {filename}")
        raise ConfigurationError(f"Missing required data file: {filename}")
    except PermissionError:
        logger.error(f"No permission to read customer data file: {filename}")
        raise ConfigurationError(f"Cannot access required data file: {filename}")

    logger.info(f"Successfully processed {len(customers)} customer records")
    return customers

This function demonstrates nested exception handling, specific exception types, and custom exceptions—all crucial for robust data processing.

Read How to Write to a File Without Newline in Python?

Conclusion

In this tutorial, I explained how Python Catch Multiple Exceptions. I discussed four important methods to accomplish this task such as using multiple except blocks, catching multiple exceptions in a single except block, using exception hierarchies, using else and finally clauses, and using exception groups. I also covered best practices, common Python exceptions, and real-time applications.

You may read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.