Python Multiple Exceptions
Table of Contents
In the last lesson, we learned about Python try and except. Now let’s handle several kinds of errors with clear exception blocks.
Let’s Talk About Handling More Than One Error
We know how to use try and except. We put risky code in try. And we handle errors in except.
But what if our code can raise more than one type of exception? We need to handle each one. Or maybe handle some together.
That is what multiple exceptions are about.
Why Multiple Exceptions in Python?
Let’s look at a simple example.
try: number = int(input("Enter a number: ")) result = 100 / number print(result)except: print("Something went wrong")This works. But it catches everything. If the user enters hello, it catches ValueError. If they enter 0, it catches ZeroDivisionError. Same message for both.
But what if we want different messages? Like “That is not a number” for one error, and “Cannot divide by zero” for another.
That is when we need multiple except blocks.
Multiple except Blocks in Python
We can have as many except blocks as we want. Each one handles a specific exception.
try: number = int(input("Enter a number: ")) result = 100 / number print(result)except ValueError: print("That is not a valid number")except ZeroDivisionError: print("Cannot divide by zero")Now if the user enters hello, it prints “That is not a valid number”. If they enter 0, it prints “Cannot divide by zero”.
Each error gets its own message. That is much better.
The Order of except Blocks in Python
Python checks the except blocks from top to bottom. It runs the first one that matches the exception.
So the order matters.
try: number = int(input("Enter a number: ")) result = 100 / number print(result)except Exception: print("Some error occurred")except ValueError: print("That is not a valid number")Here, the first except catches Exception. That is the base class for all exceptions. So it catches everything. The second except for ValueError will never run. Because the first one already caught it.
So let’s always put specific exceptions first. And general ones later.
try: number = int(input("Enter a number: ")) result = 100 / number print(result)except ValueError: print("That is not a valid number")except ZeroDivisionError: print("Cannot divide by zero")except Exception: print("Some other error occurred")Now ValueError is checked first. Then ZeroDivisionError. Then Exception. That is the correct order.
Catching Multiple Exceptions in One Block
Sometimes we want to handle several exceptions the same way. We can group them in a tuple.
try: number = int(input("Enter a number: ")) result = 100 / number print(result)except (ValueError, ZeroDivisionError): print("Invalid input or division by zero")This catches either ValueError or ZeroDivisionError. And prints the same message.
That is useful when the handling is the same.
Getting the Exception Object in Python
We can capture the exception object to see the actual error message.
try: number = int(input("Enter a number: ")) result = 100 / number print(result)except ValueError as e: print(f"ValueError: {e}")except ZeroDivisionError as e: print(f"ZeroDivisionError: {e}")If the user enters hello, the output is:
ValueError: invalid literal for int() with base 10: 'hello'That gives more detail. It can be useful for debugging or logging.
Nested try-except in Python
We can have a try block inside another try block. But let’s be careful. It can get confusing.
try: number = int(input("Enter a number: ")) try: result = 100 / number print(result) except ZeroDivisionError: print("Cannot divide by zero")except ValueError: print("That is not a valid number")The outer try handles ValueError. The inner try handles ZeroDivisionError.
This works. But it is often simpler to use multiple except blocks in one try.
Python Multiple Exceptions: A Real-Life Example
Let’s say we are reading a file and processing its contents.
try: filename = input("Enter filename: ") file = open(filename, "r") content = file.read() number = int(content) result = 100 / number print(f"Result: {result}") file.close()except FileNotFoundError: print("File not found")except ValueError: print("File does not contain a valid number")except ZeroDivisionError: print("File contains zero, cannot divide")except Exception as e: print(f"An unexpected error occurred: {e}")This handles several possible errors.
- The file does not exist:
FileNotFoundError - The file content is not a number:
ValueError - The number is zero:
ZeroDivisionError - Anything else:
Exception
That is a robust way to handle multiple exceptions.
Catching Multiple Exceptions in a Loop
Let’s ask the user for a number until they enter a valid one.
while True: try: number = int(input("Enter a number: ")) break except ValueError: print("That is not a valid number. Try again.")This only handles ValueError. But what if we also want to handle KeyboardInterrupt? That happens when the user presses Ctrl+C.
while True: try: number = int(input("Enter a number: ")) break except ValueError: print("That is not a valid number. Try again.") except KeyboardInterrupt: print("\nGoodbye!") breakNow if the user presses Ctrl+C, it exits gracefully. That is a nice touch.
Common Mistakes with Python Multiple Exceptions
Mistake 1: Putting General Exceptions Before Specific Ones
try: # some codeexcept Exception: print("Error")except ValueError: print("Value error")The ValueError block will never run. Because Exception catches it first.
So what do we do? We put specific exceptions first.
except ValueError: print("Value error")except Exception: print("Error")Mistake 2: Catching Too Much
try: # some codeexcept: passThis catches everything and does nothing. It hides bugs. Let’s always catch specific exceptions.
Mistake 3: Using the Same Handler for Different Errors
Sometimes it is fine. But often different errors need different handling. Let’s not group them just to save lines. Let’s be clear.
Mistake 4: Forgetting That the Order of except Blocks Matters
We already covered this. But it is worth repeating. Python checks from top to bottom. So let’s put specific exceptions first.
A Real-Life Example with User Input
Let’s build a simple calculator that handles multiple exceptions.
try: num1 = float(input("Enter first number: ")) num2 = float(input("Enter second number: ")) operation = input("Enter operation (+, -, *, /): ")
if operation == "+": result = num1 + num2 elif operation == "-": result = num1 - num2 elif operation == "*": result = num1 * num2 elif operation == "/": result = num1 / num2 else: raise ValueError("Invalid operation")
print(f"Result: {result}")
except ValueError as e: print(f"Error: {e}")except ZeroDivisionError: print("Cannot divide by zero")except Exception as e: print(f"Unexpected error: {e}")This handles bad numbers, division by zero, invalid operations, and anything else.
Next, we will learn about the Python finally Block and run cleanup code whether an error happens or not.