π¨ 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 subclass | Inheriting from BaseException directly |
| Use meaningful names and docstrings | Using vague names like Error1, Bug |
| Create a base class for your app/library | Duplicating logic in multiple exceptions |
| Catch specific exceptions when possible | Catching 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 fromto 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 :
