Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 Beginner🔵 Advanced
Exceptions OverviewException TypesTry-Except BlocksRaising ExceptionsCustom ExceptionsMultiple ExceptionsFinally & CleanupDebugging TechniquesLogging Best Practices
Python/Error Handling/Raising Exceptions

🎯 Raising Exceptions — Signaling Errors in Your Code

Learn how to intentionally raise exceptions to enforce rules and signal problems in your functions.


🚀 Basic Exception Raising

You can deliberately raise exceptions using the `raise` keyword:

# Raise a built-in exception
def get_age(age_input):
    try:
        age = int(age_input)
    except ValueError:
        raise ValueError("Age must be a valid number")

# Test it
try:
    age = get_age("not a number")
except ValueError as e:
    print(f"Caught error: {e}")

# Output: Caught error: Age must be a number

📋 Validating Input with Exceptions

A common use case is validating function parameters:

# Validate age range
def create_student(name, age):
    # Check inputs
    if not isinstance(name, str):
        raise TypeError("Name must be a string")

    if not isinstance(age, int):
        raise TypeError("Age must be an integer")

    if age < 5:
        raise ValueError("Age must be at least 5")

    if age > 120:
        raise ValueError("Age seems unrealistic")

    if len(name) == 0:
        raise ValueError("Name cannot be empty")

    return {"name": name, "age": age}

# Valid input
try:
    student = create_student("Alice", 15)
    print(f"Created: {student}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

# Invalid inputs
try:
    create_student(123, 15)  # TypeError: Name must be a string
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

try:
    create_student("Bob", 3)  # ValueError: Age must be at least 5
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

🔄 Re-raising Exceptions

Sometimes you catch an exception, do something, then raise it again:

# Logging then re-raising
def process_file(filename):
    try:
        with open(filename) as f:
            return f.read()
    except FileNotFoundError as e:
        print(f"Warning: {filename} not found!")
        raise  # Re-raise the same exception

# The caller must handle it
try:
    content = process_file("missing.txt")
except FileNotFoundError:
    print("Could not read file, using default content")

# Different example: wrap and re-raise
def database_query(query):
    try:
        # Simulate database call
        if "DROP" in query:
            raise RuntimeError("Dangerous query!")
    except RuntimeError as e:
        print(f"Query rejected: {e}")
        raise  # Let caller know it failed

# Caller can catch it
try:
    database_query("DROP TABLE users")
except RuntimeError:
    print("Database error occurred")

🏗️ Raising Different Exceptions Based on Conditions

# Bank account withdrawal
def withdraw(balance, amount):
    if amount < 0:
        raise ValueError("Cannot withdraw negative amount")

    if amount == 0:
        raise ValueError("Must withdraw at least 1 cent")

    if amount > balance:
        raise ValueError(f"Insufficient funds. Balance: ${balance}")

    return balance - amount

# Test different scenarios
balance = 100.00

try:
    balance = withdraw(balance, 30)
    print(f"New balance: ${balance}")
except ValueError as e:
    print(f"Withdrawal failed: {e}")

try:
    balance = withdraw(balance, -10)
except ValueError as e:
    print(f"Withdrawal failed: {e}")

try:
    balance = withdraw(balance, 200)
except ValueError as e:
    print(f"Withdrawal failed: {e}")

📊 Real-World Examples

# Example 1: Email validation
def validate_email(email):
    if not isinstance(email, str):
        raise TypeError("Email must be a string")

    if "@" not in email:
        raise ValueError("Email must contain @")

    if email.count("@") > 1:
        raise ValueError("Email can only have one @")

    if "." not in email.split("@")[1]:
        raise ValueError("Domain must contain a dot")

    return True

try:
    validate_email("alice@example.com")
    print("Email is valid!")
except (TypeError, ValueError) as e:
    print(f"Invalid email: {e}")

try:
    validate_email("invalid.email")
except ValueError as e:
    print(f"Invalid email: {e}")

# Example 2: Password validation
def validate_password(password):
    if len(password) < 8:
        raise ValueError("Password must be at least 8 characters")

    if not any(c.isupper() for c in password):
        raise ValueError("Password must contain uppercase letter")

    if not any(c.isdigit() for c in password):
        raise ValueError("Password must contain a digit")

    return True

try:
    validate_password("Weak123")
    print("Password is valid!")
except ValueError as e:
    print(f"Password error: {e}")

# Example 3: Safe division with custom error
def safe_divide(a, b):
    if not isinstance(a, (int, float)):
        raise TypeError(f"First argument must be number, got {type(a).__name__}")

    if not isinstance(b, (int, float)):
        raise TypeError(f"Second argument must be number, got {type(b).__name__}")

    if b == 0:
        raise ZeroDivisionError("Cannot divide by zero")

    return a / b

try:
    result = safe_divide(10, 2)
    print(f"Result: {result}")
except (TypeError, ZeroDivisionError) as e:
    print(f"Calculation error: {e}")

try:
    result = safe_divide(10, "five")
except TypeError as e:
    print(f"Type error: {e}")

🎨 Exception Messages Matter

# ❌ Unhelpful error message
def bad_validate(age):
    if age < 0:
        raise ValueError("Error")  # What error?

# ✅ Helpful error message
def good_validate(age):
    if age < 0:
        raise ValueError(f"Age cannot be negative. Got: {age}")
    if age > 150:
        raise ValueError(f"Age seems unrealistic. Got: {age}")
    return True

# Good practice: include context
def validate_score(score, max_score):
    if not isinstance(score, (int, float)):
        raise TypeError(f"Score must be number, got {type(score).__name__}")

    if score < 0:
        raise ValueError(f"Score cannot be negative. Got {score}")

    if score > max_score:
        raise ValueError(
            f"Score {score} exceeds maximum of {max_score}"
        )

    return True

try:
    validate_score(105, 100)
except ValueError as e:
    print(f"Score validation failed: {e}")

⚠️ When to Raise Exceptions

Raise exceptions when:

  • ✅ Input validation fails
  • ✅ Preconditions aren't met
  • ✅ Data is in invalid state
  • ✅ Operation cannot proceed safely

Don't raise exceptions for:

  • ❌ Normal control flow (use `if` statements instead)
  • ❌ Expected outcomes
  • ❌ Just because you can

🎯 Key Takeaways

  • ✅ Use `raise` keyword to throw exceptions
  • ✅ Raise exceptions for input validation
  • ✅ Provide clear, helpful error messages
  • ✅ Raise specific exception types
  • ✅ Can re-raise exceptions with `raise` (no arguments)
  • ✅ Helps callers handle errors appropriately


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn