🚨 Python Custom Exceptions β€” Creating Your Own Error Types

Introduction 🌟

Python allows you to create your own exceptions, known asCustom Exceptions. These are useful when the built-in exceptions don't describe your error clearly.

Note

πŸ’‘ Custom exceptions make your code more readable, structured, and easier to debug.

1. Creating Your First Custom Exception 🧱

All custom exceptions must inherit from Exception (or any of its subclasses).

basic_custom_exception.py

class MyError(Exception):
    pass

try:
    raise MyError("Something went wrong!")
except MyError as e:
    print("Caught custom error:", e)

βœ” The pass keyword is enough for simple custom exceptions.

2. Adding a Custom Message πŸŽ™οΈ

custom_message.py

class AgeError(Exception):
    def __init__(self, message):
        super().__init__(message)

def check_age(age):
    if age < 0:
        raise AgeError("Age cannot be negative!")

try:
    check_age(-5)
except AgeError as e:
    print("❌", e)

3. Custom Exception with Additional Attributes πŸ“¦

exception_attributes.py

class LoginError(Exception):
    def __init__(self, username, message):
        self.username = username
        super().__init__(message)

try:
    raise LoginError("admin", "Invalid password")
except LoginError as e:
    print("User:", e.username)
    print("Error:", e)

Note

βœ” You can store extra data inside custom exceptions.

4. Using Custom Exceptions in Functions 🎯

function_custom_exception.py

class NegativeNumberError(Exception):
    pass

def square_root(n):
    if n < 0:
        raise NegativeNumberError("Cannot take square root of negative number")
    return n ** 0.5

try:
    print(square_root(-9))
except NegativeNumberError as e:
    print("❌", e)

5. Creating a Hierarchy of Custom Exceptions 🧩

error_hierarchy.py

class AppError(Exception):
    pass

class FileError(AppError):
    pass

class NetworkError(AppError):
    pass

try:
    raise NetworkError("Network unreachable")
except NetworkError as e:
    print("❌", e)
except AppError:
    print("General application error")

βœ” Hierarchies make large applications more maintainable.

6. Using Custom Exceptions for Validation πŸ“

validation_example.py

class EmailError(Exception):
    pass

def validate_email(email):
    if "@" not in email:
        raise EmailError("Invalid email format")

try:
    validate_email("hello.com")
except EmailError as e:
    print("❌", e)

7. Raising Built-In Exceptions vs Custom Exceptions βš”οΈ

Built-in ExceptionCustom Exception
Generic error messageMeaningful app-specific message
No custom attributesCan include extra information
Good for common errorsGood for domain-specific logic

8. Real-World Example: Banking System πŸ’°

banking_example.py

class InsufficientFundsError(Exception):
    pass

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError("Not enough balance")
    return balance - amount

try:
    print(withdraw(500, 800))
except InsufficientFundsError as e:
    print("❌", e)

9. Real-World Example: Authentication System πŸ”

auth_example.py

class UserNotFoundError(Exception):
    pass

class WrongPasswordError(Exception):
    pass

def login(username, password):
    users = {"admin": "123"}
    if username not in users:
        raise UserNotFoundError("User does not exist")
    if users[username] != password:
        raise WrongPasswordError("Incorrect password")
    return "Login successful!"

try:
    print(login("root", "123"))
except UserNotFoundError as e:
    print("❌", e)
except WrongPasswordError as e:
    print("❌", e)

10. Custom Exceptions in Large Applications 🌍

  • βœ” Better debugging and logging
  • βœ” Cleaner separation of error types
  • βœ” Works well with multi-module projects
  • βœ” Helps build professional-grade libraries

11. Best Practices πŸ’‘

  • βœ” Inherit from Exception, not BaseException
  • βœ” Use clear, meaningful names (e.g., AgeError, LoginError)
  • βœ” Provide informative messages
  • βœ” Group related exceptions using class hierarchy
  • βœ” Avoid overusing custom exceptions

Conclusion πŸŽ‰

>>β€œCustom Exceptions let you define meaningful, domain-specific errors β€” making your applications clean, predictable, and easier to maintain.” ✨

You now fully understand Custom Exceptions in Python! Want the next topic? Try Raising Exceptions, Error Hierarchies, Logging, or File Handling. Just tell me! 😊