PyGuide

Learn Python with practical tutorials and code examples

Code Snippet Intermediate
• Updated Jul 22, 2024

Python What Error to Raise: Code Examples and Patterns

Practical code snippets showing what error to raise in Python. Copy-paste examples for ValueError, TypeError, AttributeError, and custom exceptions.

Python What Error to Raise: Code Examples and Patterns

Quick reference code snippets showing what error to raise in different Python scenarios. Copy and adapt these examples for your projects.

Input Validation Patterns #

Type Validation - Use TypeError #

def validate_string_input(value, param_name="value"):
    """Validate that input is a string"""
    if not isinstance(value, str):
        raise TypeError(f"{param_name} must be a string, got {type(value).__name__}")
    return value

# Usage examples
try:
    validate_string_input(123, "username")
except TypeError as e:
    print(f"Type error: {e}")

Value Range Validation - Use ValueError #

def validate_age(age):
    """Validate age is within reasonable range"""
    if not isinstance(age, int):
        raise TypeError("Age must be an integer")
    if age < 0:
        raise ValueError("Age cannot be negative")
    if age > 150:
        raise ValueError("Age cannot exceed 150 years")
    return age

# Usage examples
test_ages = [25, -5, 200, "thirty"]
for age in test_ages:
    try:
        valid_age = validate_age(age)
        print(f"Valid age: {valid_age}")
    except (TypeError, ValueError) as e:
        print(f"Invalid age {age}: {e}")

Object State Validation #

Missing Required Attributes - Use AttributeError #

class UserProfile:
    def __init__(self, username):
        self.username = username
    
    def get_email(self):
        if not hasattr(self, 'email'):
            raise AttributeError(f"UserProfile '{self.username}' has no email attribute")
        return self.email
    
    def get_full_name(self):
        if not hasattr(self, 'first_name') or not hasattr(self, 'last_name'):
            raise AttributeError("Both first_name and last_name must be set")
        return f"{self.first_name} {self.last_name}"

# Usage examples
user = UserProfile("john_doe")
try:
    email = user.get_email()
except AttributeError as e:
    print(f"Missing attribute: {e}")
    user.email = "[email protected]"
    print(f"Email: {user.get_email()}")

Invalid Object State - Use RuntimeError #

class Connection:
    def __init__(self):
        self.is_connected = False
        self.is_authenticated = False
    
    def connect(self):
        self.is_connected = True
        print("Connected")
    
    def authenticate(self, token):
        if not self.is_connected:
            raise RuntimeError("Must connect before authenticating")
        self.is_authenticated = True
        print("Authenticated")
    
    def send_data(self, data):
        if not self.is_connected:
            raise RuntimeError("Connection not established")
        if not self.is_authenticated:
            raise RuntimeError("Must authenticate before sending data")
        return f"Sent: {data}"

# Usage examples
conn = Connection()
try:
    conn.send_data("Hello")
except RuntimeError as e:
    print(f"Runtime error: {e}")
    # Fix the state
    conn.connect()
    conn.authenticate("token123")
    print(conn.send_data("Hello"))

Collection Access Patterns #

Dictionary Key Access - Use KeyError #

def get_config_value(config, key):
    """Get configuration value with specific error"""
    if not isinstance(config, dict):
        raise TypeError("Config must be a dictionary")
    if key not in config:
        raise KeyError(f"Configuration key '{key}' not found. Available keys: {list(config.keys())}")
    return config[key]

# Safe dictionary access alternative
def safe_get_config(config, key, default=None):
    try:
        return get_config_value(config, key)
    except KeyError:
        return default

# Usage examples
config = {"database_url": "localhost", "port": 5432}
try:
    value = get_config_value(config, "api_key")
except KeyError as e:
    print(f"Key error: {e}")
    # Use safe access
    api_key = safe_get_config(config, "api_key", "default_key")
    print(f"Using default: {api_key}")

List Index Access - Use IndexError #

def get_list_item_safe(items, index, context="list"):
    """Safe list access with descriptive error"""
    if not isinstance(items, (list, tuple)):
        raise TypeError(f"Expected list or tuple, got {type(items).__name__}")
    if not isinstance(index, int):
        raise TypeError("Index must be an integer")
    
    length = len(items)
    if index >= length or index < -length:
        raise IndexError(
            f"Index {index} out of range for {context} of length {length}. "
            f"Valid range: {-length} to {length-1}"
        )
    return items[index]

# Usage examples
numbers = [10, 20, 30]
try:
    item = get_list_item_safe(numbers, 5, "numbers list")
except IndexError as e:
    print(f"Index error: {e}")

Mathematical Operations #

Division by Zero - Use ZeroDivisionError #

def safe_divide(numerator, denominator, precision=2):
    """Safe division with specific error handling"""
    if not isinstance(numerator, (int, float)):
        raise TypeError(f"Numerator must be a number, got {type(numerator).__name__}")
    if not isinstance(denominator, (int, float)):
        raise TypeError(f"Denominator must be a number, got {type(denominator).__name__}")
    if denominator == 0:
        raise ZeroDivisionError("Cannot divide by zero")
    
    result = numerator / denominator
    return round(result, precision)

# Usage examples
test_cases = [(10, 2), (15, 0), ("10", 2)]
for num, den in test_cases:
    try:
        result = safe_divide(num, den)
        print(f"{num} / {den} = {result}")
    except (TypeError, ZeroDivisionError) as e:
        print(f"Error dividing {num} by {den}: {e}")

Invalid Mathematical Operations - Use ValueError #

import math

def safe_sqrt(number):
    """Safe square root calculation"""
    if not isinstance(number, (int, float)):
        raise TypeError(f"Number must be int or float, got {type(number).__name__}")
    if number < 0:
        raise ValueError(f"Cannot calculate square root of negative number: {number}")
    return math.sqrt(number)

def safe_log(number, base=math.e):
    """Safe logarithm calculation"""
    if not isinstance(number, (int, float)):
        raise TypeError("Number must be int or float")
    if number <= 0:
        raise ValueError(f"Logarithm undefined for non-positive numbers: {number}")
    if base <= 0 or base == 1:
        raise ValueError(f"Invalid logarithm base: {base}")
    return math.log(number, base)

# Usage examples
try:
    result = safe_sqrt(-4)
except ValueError as e:
    print(f"Math error: {e}")

try:
    result = safe_log(0)
except ValueError as e:
    print(f"Math error: {e}")

Custom Exception Patterns #

Domain-Specific Exceptions #

# Base exception class
class PaymentError(Exception):
    """Base exception for payment operations"""
    pass

# Specific payment exceptions
class InsufficientFundsError(PaymentError):
    def __init__(self, required, available):
        self.required = required
        self.available = available
        super().__init__(f"Insufficient funds: need ${required}, have ${available}")

class InvalidPaymentMethodError(PaymentError):
    def __init__(self, method):
        self.method = method
        super().__init__(f"Invalid payment method: {method}")

class PaymentProcessingError(PaymentError):
    def __init__(self, transaction_id, reason):
        self.transaction_id = transaction_id
        self.reason = reason
        super().__init__(f"Payment {transaction_id} failed: {reason}")

# Payment processor class
class PaymentProcessor:
    def __init__(self):
        self.valid_methods = ["credit_card", "debit_card", "paypal"]
    
    def process_payment(self, amount, method, account_balance=100):
        # Validate payment method
        if method not in self.valid_methods:
            raise InvalidPaymentMethodError(method)
        
        # Check sufficient funds
        if amount > account_balance:
            raise InsufficientFundsError(amount, account_balance)
        
        # Simulate processing error
        if amount > 1000:
            raise PaymentProcessingError("TXN123", "Amount exceeds daily limit")
        
        return f"Payment of ${amount} processed successfully"

# Usage examples
processor = PaymentProcessor()
test_payments = [
    (50, "credit_card", 100),    # Success
    (150, "credit_card", 100),   # Insufficient funds
    (75, "bitcoin", 100),        # Invalid method
    (1500, "credit_card", 2000)  # Processing error
]

for amount, method, balance in test_payments:
    try:
        result = processor.process_payment(amount, method, balance)
        print(f"✓ {result}")
    except InsufficientFundsError as e:
        print(f"✗ {e} (need ${e.required - e.available} more)")
    except InvalidPaymentMethodError as e:
        print(f"✗ {e} (valid methods: {processor.valid_methods})")
    except PaymentProcessingError as e:
        print(f"✗ {e}")

File Operation Error Patterns #

import os

def safe_file_operation(filename, operation="read", content=None):
    """Safe file operations with specific error handling"""
    if not isinstance(filename, str):
        raise TypeError("Filename must be a string")
    if not filename.strip():
        raise ValueError("Filename cannot be empty")
    
    if operation == "read":
        try:
            with open(filename, 'r') as f:
                return f.read()
        except FileNotFoundError:
            raise FileNotFoundError(f"File '{filename}' does not exist")
        except PermissionError:
            raise PermissionError(f"No permission to read '{filename}'")
    
    elif operation == "write":
        if content is None:
            raise ValueError("Content is required for write operation")
        try:
            with open(filename, 'w') as f:
                f.write(content)
            return f"Successfully wrote to '{filename}'"
        except PermissionError:
            raise PermissionError(f"No permission to write to '{filename}'")
    
    else:
        raise ValueError(f"Unknown operation '{operation}'. Use 'read' or 'write'")

# Usage examples
try:
    content = safe_file_operation("nonexistent.txt", "read")
except FileNotFoundError as e:
    print(f"File error: {e}")

try:
    result = safe_file_operation("test.txt", "write", "Hello World")
    print(result)
except PermissionError as e:
    print(f"Permission error: {e}")

Quick Reference Guide #

ScenarioError TypeUsage
Wrong data typeTypeErrorisinstance() checks fail
Right type, wrong valueValueErrorValid type but invalid value
Missing attribute/methodAttributeErrorhasattr() checks fail
Missing dictionary keyKeyErrorKey not in dictionary
Invalid list/tuple indexIndexErrorIndex out of bounds
Invalid runtime stateRuntimeErrorObject in wrong state
Method not implementedNotImplementedErrorAbstract method placeholders
Division by zeroZeroDivisionErrorMathematical division errors
Domain-specific issuesCustom ExceptionBusiness logic errors

Usage Tips #

  1. Be specific: Choose the most appropriate exception type
  2. Provide context: Include helpful error messages with values
  3. Chain exceptions: Use raise ... from ... when catching and re-raising
  4. Document exceptions: List expected exceptions in docstrings
  5. Test error paths: Write tests for your exception handling

These patterns help you write robust Python code with clear, actionable error messages.

Related Snippets

Snippet Intermediate

Python Error Frame Inspection Code Examples

Ready-to-use Python code snippets for inspecting error frames, analyzing stack traces, and debugging frame-related issues effectively.

#python #error #frame +2
View Code
Syntax
Snippet Intermediate

Python Error Handling Code Snippets: Try-Except Examples

Ready-to-use Python error handling code snippets. Copy-paste examples for common error handling patterns and exception management.

#python #error #exception +2
View Code
Syntax
Snippet Advanced

Python Can Error Frame Analysis Code Examples

Ready-to-use Python code snippets for error frame analysis when Python can error frame issues occur. Complete debugging examples and utilities.

#python #error #frame +3
View Code
Syntax
Snippet Beginner

Python List Index Error Handling Iteration Code Examples

Ready-to-use Python code snippets for handling list index out of range errors during iteration with practical examples and utilities.

#python #list #index +3
View Code
Syntax