Exception handling (try-except) is a feature for “catching” errors that occur. However, to create robust programs, there are times when you, as a developer, must intentionally “raise” an error. For example, if unexpected data is passed to a function argument, or if processing cannot continue, you need to notify the caller.
This article explains how to use the raise statement to generate exceptions and how to use it for validating input values.
Basic Syntax of the raise Statement
To raise an exception, write the instance of the exception class you want to generate after the raise keyword. Usually, you pass a string containing the error message to the exception class constructor.
Syntax:
raise ExceptionClass("Error Message")
Commonly used exception classes include ValueError (inappropriate value), TypeError (inappropriate type), and Exception (general error).
Practical Example: Order Processing Validation
As a concrete example, let’s create a function process_order that deducts the order quantity from the stock. This function raises exceptions for the following two invalid cases:
- Type Error (
TypeError): If a non-integer (like a string) is passed as the order quantity. - Value Error (
ValueError): If the order quantity is 0 or less, or exceeds the stock.
def process_order(current_stock, order_quantity):
"""
Function to deduct order quantity from stock and return remaining stock.
"""
# 1. Check Type
# If order_quantity is not an integer (int), raise TypeError
if not isinstance(order_quantity, int):
raise TypeError(f"Order quantity must be an integer. Received type: {type(order_quantity).__name__}")
# 2. Check Value (Must be positive)
if order_quantity <= 0:
raise ValueError("Order quantity must be 1 or more.")
# 3. Check Value (Stock availability)
if current_stock < order_quantity:
raise ValueError(f"Insufficient stock. (Stock: {current_stock}, Order: {order_quantity})")
# Perform calculation only if all checks pass
remaining_stock = current_stock - order_quantity
return remaining_stock
# --- Execution Test ---
# Normal Case
try:
stock = 50
new_stock = process_order(stock, 10)
print(f"Order successful. Remaining stock: {new_stock}")
except Exception as e:
print(f"Error: {e}")
print("-" * 20)
# Abnormal Case 1: Passing a string
try:
process_order(50, "5 pieces")
except TypeError as e:
print(f"Caught Type Error: {e}")
# Abnormal Case 2: Insufficient stock
try:
process_order(50, 100)
except ValueError as e:
print(f"Caught Value Error: {e}")
Output:
Order successful. Remaining stock: 40
--------------------
Caught Type Error: Order quantity must be an integer. Received type: str
Caught Value Error: Insufficient stock. (Stock: 50, Order: 100)
Why Just Printing an Error is Not Enough
Sometimes you might see code that simply prints print("Error") and exits the function (return) when an error occurs. However, this is not recommended for libraries or reusable functions.
The reasons are:
- Caller may not notice the error: If you just
return, the program is considered to have “finished normally,” and subsequent processing continues. - Cannot force error handling: By using
raise, you force the caller to choose whether to handle it properly withtry-exceptor let the program stop.
How to Choose the Right Exception Class
When using raise, it is important to choose the exception class that best fits the situation.
TypeError: When the data type is different from what is expected (e.g., a string comes where a number is needed).ValueError: When the type is correct, but the content of the value is inappropriate (e.g., a negative value comes where a positive number is needed).FileNotFoundError: When a file does not exist.NotImplementedError: When an unimplemented feature is called.
By choosing the appropriate class, the caller can catch specific errors, such as except ValueError:.
Summary
- Use the
raisestatement to proactively generate exceptions when an operation violates the program’s specifications. - Write it in the format:
raise ExceptionClass("Message"). - Instead of just displaying a message and quitting, raising an exception delegates error handling to the caller.
- Use
TypeError,ValueError, etc., appropriately depending on the situation.
