Question

Catch Multiple Exceptions in One except Block in Python

pythonexception

Question

In Python, I know I can catch every exception like this:

try:
    # do something that may fail
except:
    # do this if anything goes wrong

I also know I can handle specific exceptions separately:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

But if I want to perform the same action for two different exceptions, the best approach I can think of is repeating the same code:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

Is there a way to catch multiple specific exceptions in a single except block, so both of these exceptions can be handled the same way? For example, is something like this possible?

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

I realize that syntax conflicts with the older form used to bind an exception object, such as:

try:
    # do something that may fail
except Exception as e:
    # handle the exception

What is the correct Python syntax for catching multiple exceptions in one except block?

Short Answer

By the end of this page, you will understand how to catch multiple exception types in a single Python except block, why Python uses a tuple for this, and how to write clear exception-handling code without repeating yourself.

Concept

In Python, you can catch multiple specific exception types in one except block by putting them inside a tuple.

except (FirstException, SecondException):
    ...

This is useful when different errors should be handled in the same way. Instead of duplicating code in multiple except blocks, you group the exception types together.

This matters because exception handling is not just about preventing crashes. It is also about:

  • making programs more robust
  • keeping code readable
  • avoiding repeated logic
  • handling only the errors you actually expect

A broad except: catches almost everything, which is often too vague and can hide bugs. Catching specific exceptions is usually better because it makes your intent clear.

For example, if both FileNotFoundError and PermissionError should show the same user message, handling them together is a clean solution.

In modern Python, this is the standard approach:

try:
    risky_operation()
except (TypeError, ValueError):
    print("Invalid input")

If you also need access to the exception object, you can still do that:

try:
    risky_operation()
except (TypeError, ValueError) as e:
    print(f"Problem: {e}")

So the key idea is:

  • one exception type: except ValueError:
  • multiple exception types: except (ValueError, TypeError):
  • multiple exception types and bind the error: except (ValueError, TypeError) as e:

Mental Model

Think of an except block like a door scanner checking badges.

  • If one specific badge is allowed, you check for one badge.
  • If several badges should go through the same door, you give the scanner a list of accepted badges.

In Python, that “list” is written as a tuple of exception classes.

except (ValueError, TypeError):

That means:

“If the error is any one of these types, run this block.”

So instead of building two separate doors that lead to the same room, you make one door that accepts both badges.

Take Quiz

Syntax and Examples

Core syntax

Catch one exception:

try:
    do_something()
except ValueError:
    print("A value error happened")

Catch multiple exceptions in one block:

try:
    do_something()
except (ValueError, TypeError):
    print("Either a value error or type error happened")

Catch multiple exceptions and keep the error object:

try:
    do_something()
except (ValueError, TypeError) as e:
    print(f"Handled error: {e}")

Beginner-friendly example

def parse_age(text):
    age = int(text)
    if age < 0:
        raise ValueError("Age cannot be negative")
    return age

user_input = "abc"

try:
    result = parse_age(user_input)
    print(result)
except (ValueError, TypeError):
    print("Please enter a valid age")

What this does

  • int(text) may raise ValueError if the string is not numeric.
  • A TypeError could happen if the wrong kind of value is passed.
  • Both errors lead to the same response, so one except block is enough.

Real built-in example

try:
    with open("config.json") as file:
        data = file.read()
        number = int(data)
except (FileNotFoundError, ValueError):
    print("Could not load a valid number from the file")

This catches either:

  • the file not existing, or
  • the file content not being a valid integer

and handles both cases the same way.

Step by Step Execution

Consider this example:

try:
    value = int("hello")
except (ValueError, TypeError) as e:
    print("Something went wrong")
    print(type(e).__name__)

Step by step

  1. Python enters the try block.
  2. It evaluates int("hello").
  3. The string "hello" cannot be converted to an integer.
  4. Python raises a ValueError.
  5. Python checks the except block:
    • Is the exception a ValueError?
    • Is it a TypeError?
  6. Since the actual error is ValueError, the match succeeds.
  7. The exception object is stored in e.
  8. Python runs the code inside the except block.
  9. Output becomes:
Something went wrong
ValueError

Another trace

try:
    value = int(None)
except (ValueError, TypeError) as e:
    print("Something went wrong")
    print(type(e).__name__)

This time:

  1. Python tries int(None).
  2. None is not a valid argument here.
  3. Python raises TypeError.
  4. The same except (ValueError, TypeError) block matches.
  5. The same handler runs.

This shows why grouping exceptions is useful: different failures can share one response.

Real World Use Cases

Catching multiple exceptions in one block is common when different problems should lead to the same fallback behavior.

User input validation

try:
    age = int(user_input)
    price = float(price_input)
except (ValueError, TypeError):
    print("Please enter valid numbers")

File loading

try:
    with open(filename) as f:
        content = f.read()
except (FileNotFoundError, PermissionError):
    print("Cannot read the file")

API response parsing

try:
    user_id = int(response["id"])
except (KeyError, ValueError, TypeError):
    print("Bad API data")

Dictionary and conversion logic

try:
    count = int(data["count"])
except (KeyError, ValueError):
    count = 0

Data processing scripts

When processing many records, you often want to skip invalid rows without stopping the entire script.

for row in rows:
    try:
        score = int(row["score"])
    except (KeyError, ValueError, TypeError):
        continue

The grouped exception handler keeps the code short and consistent.

Take Quiz

Real Codebase Usage

In real projects, developers usually catch multiple exceptions when the recovery action is identical.

Common patterns

Validation with one fallback

try:
    timeout = int(config.get("timeout"))
except (TypeError, ValueError):
    timeout = 30

If the config value is missing, wrong, or malformed, the app falls back to a default.

Guarding external input

try:
    email = payload["email"].strip()
except (KeyError, AttributeError):
    raise ValueError("Invalid payload")

Different low-level failures are turned into one clearer error.

Error logging

try:
    result = process(data)
except (ValueError, TypeError) as e:
    logger.warning("Invalid data: %s", e)

Early return in web or API code

def get_limit(params):
    try:
        return int(params.get("limit", 10))
    except (TypeError, ValueError):
        return 10

Narrow exception scope

A good codebase usually keeps the try block small:

try:
    limit = int(raw_limit)
except (TypeError, ValueError):
    limit = 10

This is better than wrapping many unrelated lines, because it makes it clear which operation may fail.

Best practice

Catch multiple exceptions together only when:

  • they are expected
  • they truly need the same response
  • the handler remains easy to understand

If the handling differs, use separate except blocks instead.

Common Mistakes

1. Forgetting the parentheses

This is wrong for multiple exceptions:

try:
    do_something()
except ValueError, TypeError:
    print("Error")

Use a tuple instead:

try:
    do_something()
except (ValueError, TypeError):
    print("Error")

2. Using bare except: too often

try:
    do_something()
except:
    print("Something failed")

This catches too much and can hide real bugs.

Better:

try:
    do_something()
except (ValueError, TypeError):
    print("Invalid input")

3. Catching exceptions that should be handled differently

Broken design:

try:
    do_something()
except (FileNotFoundError, PermissionError):
    print("File problem")

This is only good if the same response is truly enough. If one should create a file and the other should ask for permissions, separate them.

4. Putting too much code inside try

try:
    value = int(text)
    save_to_database(value)
    send_email(value)
except (ValueError, TypeError):
    print("Invalid input")

If save_to_database or send_email raises one of those exceptions, debugging gets harder.

Better:

try:
    value = int(text)
except (ValueError, TypeError):
    print("Invalid input")
else:
    save_to_database(value)
    send_email(value)

5. Confusing old and modern syntax

Old Python 2 style often looked like this:

except Exception, e:

Modern Python uses:

except Exception as e:

And for multiple exceptions:

except (ValueError, TypeError) as e:

Comparisons

PatternSyntaxWhen to useNotes
Catch everythingexcept:Rarely, for very broad cleanup or top-level safetyCan hide bugs
Catch one specific exceptionexcept ValueError:When only one known error should be handledClear and explicit
Catch multiple exceptions togetherexcept (ValueError, TypeError):When several errors need the same handlingBest for shared behavior
Catch separate exceptionsexcept ValueError: / except TypeError:When each error needs different handlingMore verbose but clearer
Catch and inspect objectexcept (ValueError, TypeError) as e:When you need the error message or typeUseful for logging

Multiple exceptions together vs separate blocks

try:
    do_something()
except (ValueError, TypeError):
    print("Invalid input")

Use this when both errors mean the same thing to your program.

try:
    do_something()
except ValueError:
    print("Bad value")
except TypeError:
    print("Wrong type")

Use separate blocks when the response should differ.

except: vs except Exception:

except:
  • catches almost everything
  • usually too broad
except Exception:
  • still broad, but more explicit
  • often preferred over bare except: when broad handling is truly needed

Most of the time, catching specific exceptions is the best choice.

Take Quiz

Cheat Sheet

# One exception
try:
    do_something()
except ValueError:
    handle_error()

# Multiple exceptions
try:
    do_something()
except (ValueError, TypeError):
    handle_error()

# Multiple exceptions with error object
try:
    do_something()
except (ValueError, TypeError) as e:
    print(e)

Rules

  • Use parentheses for multiple exceptions.
  • Put exception classes inside the tuple.
  • Use as e if you need the exception object.
  • Catch specific exceptions whenever possible.
  • Use one block only if all listed exceptions should be handled the same way.

Good pattern

try:
    value = int(text)
except (TypeError, ValueError):
    value = 0

Avoid

except:
    pass

This hides errors and makes debugging difficult.

Remember

  • except ValueError: → one exception
  • except (ValueError, TypeError): → multiple exceptions
  • except (ValueError, TypeError) as e: → multiple exceptions plus the error object

FAQ

Can Python catch multiple exceptions in one except block?

Yes. Put the exception types in a tuple:

except (ValueError, TypeError):

How do I catch multiple exceptions and access the error message?

Use as e:

except (ValueError, TypeError) as e:
    print(e)

Why do I need parentheses around multiple exceptions?

Because Python expects a single object after except, and a tuple groups multiple exception classes into one object.

Is except: the same as catching multiple exceptions?

No. except: catches almost everything, while except (A, B): catches only the listed exception types.

Should I combine exceptions or keep them separate?

Combine them only if the handling is the same. If each exception needs different logic, use separate except blocks.

Does this work with built-in exceptions?

Yes. For example:

except (FileNotFoundError, PermissionError):

What is the modern syntax for binding the exception object?

Use as:

except ValueError as e:

or

except (ValueError, TypeError) as e:
Take Quiz

Mini Project

Description

Build a small Python input parser that reads values from a dictionary and safely converts them into usable application settings. This demonstrates how multiple exceptions can be handled together when different failures should lead to the same fallback behavior.

Goal

Create a function that reads a user's age and height from a dictionary, converts them to numbers, and returns safe default values when the input is missing or invalid.

Requirements

  • Create a function that accepts a dictionary of user data.
  • Read age and height from the dictionary.
  • Convert age to an integer and height to a float.
  • If a key is missing or a value cannot be converted, use default values instead.
  • Use at least one except block that catches multiple exceptions together.
Take Quiz

Keep learning

Related questions

View more