💡 Advanced Python Concepts
Estimated reading: 3 minutes 392 views

🚨 Python Custom Exceptions – Create Meaningful Errors with Clarity

Introduction – Why Create Custom Exceptions?

Python provides built-in exceptions like ValueError, TypeError, and KeyError, but sometimes your application needs domain-specific error handling.

Custom exceptions help you:

  • Raise meaningful and readable errors
  • Handle errors at different layers of the codebase
  • Provide cleaner debugging and logging
  • Separate your business logic from system errors

In this guide, you’ll learn:

  • What custom exceptions are
  • How to define and raise your own exception classes
  • Real-world use cases
  • Best practices for naming and structure

What Is a Custom Exception?

A custom exception is a user-defined class that inherits from Python’s built-in Exception class (or its subclasses like ValueError, RuntimeError).


How to Create a Custom Exception

Basic Custom Exception

class MyError(Exception):
    pass

raise MyError("Something went wrong")

Output:

Traceback (most recent call last):
  ...
MyError: Something went wrong

Adding Custom Behavior

class InvalidAgeError(Exception):
    def __init__(self, age, message="Age must be at least 18"):
        self.age = age
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f"{self.message}. Given: {self.age}"

Usage:

age = 16
if age < 18:
    raise InvalidAgeError(age)

Output:

InvalidAgeError: Age must be at least 18. Given: 16

Real-World Use Case – Banking App

class InsufficientFundsError(Exception):
    pass

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError("Withdrawal exceeds balance")
    return balance - amount
try:
    withdraw(100, 150)
except InsufficientFundsError as e:
    print("Error:", e)

Output:

Error: Withdrawal exceeds balance

Custom Exception Hierarchy

class AppError(Exception):
    """Base exception for the app"""

class LoginError(AppError):
    pass

class TokenExpiredError(LoginError):
    pass

class PermissionDeniedError(AppError):
    pass

This allows group catching:

try:
    raise TokenExpiredError("Session expired")
except AppError as e:
    print("App error:", e)

Raising Exceptions with raise from

Preserve original traceback:

try:
    int("abc")
except ValueError as e:
    raise MyError("Custom message") from e

Output includes both errors in traceback.


Best Practices

Do This Avoid This
Inherit from Exception or a subclassInheriting from BaseException directly
Use meaningful names and docstringsUsing vague names like Error1, Bug
Create a base class for your app/libraryDuplicating logic in multiple exceptions
Catch specific exceptions when possibleCatching broad except: unless needed

Summary – Recap & Next Steps

Python custom exceptions give you fine-grained control over error handling. They’re a best practice for clean, maintainable, and readable code.

Key Takeaways:

  • Create custom exceptions by inheriting from Exception
  • Use meaningful messages and attributes
  • Build a hierarchy for better organization
  • Use raise from to preserve traceback

Real-World Relevance:
Used in web apps, data pipelines, API design, and business logic validation.


FAQ – Python Custom Exceptions

What class should I inherit from?

Use Exception or its subclasses (ValueError, RuntimeError, etc.)

Can I create a hierarchy of exceptions?

Yes. It’s good practice to create a base class like AppError and subclass from it.

Is raise from required?

No. But it’s helpful when chaining exceptions to maintain full traceback.

Can I add custom attributes to exceptions?

Yes. Define them in __init__() and override __str__() if needed.

Should I catch all exceptions with except:?

Avoid unless you’re logging or cleaning up. Always prefer catching specific exceptions.


Share Now :
Share

Python Custom Exceptions

Or Copy Link

CONTENTS
Scroll to Top