In programming, more than one type of error (exception) can occur within a single block of code. For example, data loading might fail because “file not found,” “invalid data format,” or “missing required value.” Python’s try-except statement allows you to implement appropriate responses (error handling) for each error type by writing multiple except blocks.
This article explains the syntax for catching multiple exceptions and important rules for writing them.
Basic Syntax for Catching Multiple Exceptions
List as many except blocks as the number of exceptions you want to catch after the try block.
Syntax:
try:
# Process where errors might occur
except ExceptionA:
# Process when ExceptionA occurs
except ExceptionB:
# Process when ExceptionB occurs
except Exception:
# Process when any other exception occurs
The program evaluates the except clauses in order from top to bottom, and executes the block as soon as it finds a type that matches (or inherits from) the occurred exception. Only one except block is executed.
Sample Code: Verifying Server Configuration
As a specific example, let’s create a function that reads server configuration information (dictionary data) and calculates the memory allocation per process. The following errors are expected:
- Configuration item (key) does not exist (
KeyError) - Process count is 0, making division impossible (
ZeroDivisionError) - Configuration value is not a number (
TypeError)
def calculate_memory_per_process(server_config):
print("--- Starting config verification and calculation ---")
try:
# Get values from dictionary (KeyError if key missing)
total_mem = server_config["total_memory_gb"]
proc_count = server_config["process_count"]
# Execute division (ZeroDivisionError if proc_count is 0)
# TypeError if value is string etc. during division
memory_allocation = total_mem / proc_count
print(f"Success: Allocating {memory_allocation:.2f} GB per process.")
except KeyError as e:
print(f"Config Error: Required key {e} not found.")
except ZeroDivisionError:
print("Numeric Error: Process count cannot be 0.")
except TypeError:
print("Type Error: Memory capacity and process count must be numbers.")
except Exception as e:
# Catch unexpected errors
print(f"Unexpected error occurred: {e}")
print("--- Process End ---\n")
# --- Execution Test ---
# 1. Valid Data
valid_data = {"total_memory_gb": 32, "process_count": 4}
calculate_memory_per_process(valid_data)
# 2. Missing Key (KeyError)
missing_key_data = {"total_memory_gb": 32}
calculate_memory_per_process(missing_key_data)
# 3. Zero Division (ZeroDivisionError)
zero_proc_data = {"total_memory_gb": 32, "process_count": 0}
calculate_memory_per_process(zero_proc_data)
# 4. Invalid Type (TypeError)
invalid_type_data = {"total_memory_gb": "32GB", "process_count": 4}
calculate_memory_per_process(invalid_type_data)
Output:
--- Starting config verification and calculation ---
Success: Allocating 8.00 GB per process.
--- Process End ---
--- Starting config verification and calculation ---
Config Error: Required key 'process_count' not found.
--- Process End ---
--- Starting config verification and calculation ---
Numeric Error: Process count cannot be 0.
--- Process End ---
--- Starting config verification and calculation ---
Type Error: Memory capacity and process count must be numbers.
--- Process End ---
As shown, you can display appropriate error messages depending on the type of error that occurred.
Order of Exception Handling and Parent Classes
When writing multiple except blocks, be aware of the inheritance relationship of exception classes. Python exceptions have a class hierarchy, and Exception is the parent class of almost all exceptions. Therefore, if you write except Exception: first, all errors will be caught there, and subsequent individual except blocks (like KeyError) will never be reached.
Bad Example:
try:
# Process
except Exception:
# Everything stops here
print("Error")
except KeyError:
# Never reached (Dead code)
print("Key Error")
Rule: Write specific, detailed exceptions (child classes) first, and comprehensive exceptions (parent classes like Exception) last.
Handling Multiple Exceptions Together
If you want to perform exactly the same processing for different types of exceptions, you can specify exception classes as a tuple.
except (ValueError, TypeError) as e:
print(f"There is a problem with the value or type: {e}")
This prevents code duplication and allows for concise writing.
Summary
- In the
try-exceptsyntax, you can write multipleexceptblocks to branch processing for each error type. - Handling expected specific errors like
KeyErrororZeroDivisionErrorindividually makes the program robust. - The order of
exceptis important. Write specific exceptions first and comprehensive exceptions likeExceptionlast.
