TEACHER THEORY ABOUT CUSTOM
ERROR :-
Raising Custom errors
In python, we can raise custom errors by using the raise keyword.
salary = int(input("Enter salary amount: "))
if not 2000 < salary < 5000:
raise ValueError("Not a valid salary")
In the previous tutorial, we learned about different built-in exceptions in Python and why it is
important to handle exceptions. However, sometimes we may need to create our own custom
exceptions that serve our purpose.
Defining Custom Exceptions
In Python, we can define custom exceptions by creating a new class that is derived from the
built-in Exception class.
Here's the syntax to define custom exceptions:
class CustomError(Exception):
# code ...
pass
try:
# code ...
except CustomError:
# code...
This is useful because sometimes we might want to do something when a particular exception
is raised. For example, sending an error report to the admin, calling an api, etc.
Ai theory :-
Custom exceptions in Python let you create your own error types that are specific to
your application's needs. Here's how they work:
Basic Custom Exception
python
class CustomError(Exception):
pass
# Using it
def divide_numbers(a, b):
if b == 0:
raise CustomError("Cannot divide by zero!")
return a / b
try:
result = divide_numbers(10, 0)
except CustomError as e:
print(f"Error: {e}")
More Detailed Custom Exception
python
class ValidationError(Exception):
def __init__(self, message, error_code=None):
super().__init__(message)
self.error_code = error_code
self.message = message
def __str__(self):
if self.error_code:
return f"[{self.error_code}] {self.message}"
return self.message
# Using it
def validate_age(age):
if age < 0:
raise ValidationError("Age cannot be negative", "VAL001")
if age > 150:
raise ValidationError("Age seems unrealistic", "VAL002")
try:
validate_age(-5)
except ValidationError as e:
print(f"Validation failed: {e}")
print(f"Error code: {e.error_code}")
Exception Hierarchy
You can create families of related exceptions:
python
class DatabaseError(Exception):
"""Base exception for database operations"""
pass
class ConnectionError(DatabaseError):
"""Raised when database connection fails"""
pass
class QueryError(DatabaseError):
"""Raised when SQL query fails"""
pass
def connect_to_db():
# Simulating connection failure
raise ConnectionError("Failed to connect to database server")
def execute_query(sql):
# Simulating query error
raise QueryError(f"Invalid SQL: {sql}")
# You can catch specific exceptions or the base class
try:
connect_to_db()
except ConnectionError:
print("Connection problem - trying backup server")
except DatabaseError: # Catches any database-related error
print("Database operation failed")
Practical Example
Here's a real-world example for a user registration system:
python
class UserRegistrationError(Exception):
"""Base class for user registration errors"""
pass
class InvalidEmailError(UserRegistrationError):
def __init__(self, email):
self.email = email
super().__init__(f"Invalid email format: {email}")
class WeakPasswordError(UserRegistrationError):
def __init__(self, requirements):
self.requirements = requirements
super().__init__(f"Password doesn't meet requirements:
{requirements}")
class UserExistsError(UserRegistrationError):
def __init__(self, username):
self.username = username
super().__init__(f"User '{username}' already exists")
def register_user(username, email, password):
# Email validation
if "@" not in email:
raise InvalidEmailError(email)
# Password validation
if len(password) < 8:
raise WeakPasswordError("minimum 8 characters")
# Check if user exists (simulated)
existing_users = ["john", "jane", "bob"]
if username in existing_users:
raise UserExistsError(username)
return f"User {username} registered successfully!"
# Usage with specific error handling
try:
register_user("john", "invalid-email", "123")
except InvalidEmailError as e:
print(f"Fix your email: {e.email}")
except WeakPasswordError as e:
print(f"Password issue: {e}")
except UserExistsError as e:
print(f"Try a different username, {e.username} is taken")
except UserRegistrationError as e:
print(f"Registration failed: {e}")
Key Benefits
1. Clarity: Your code communicates exactly what went wrong
2. Specific handling: You can handle different errors differently
3. Debugging: Easier to trace and fix issues
4. API design: Clean error reporting for users of your code
Best Practices
• Inherit from Exception or a more specific built-in exception
• Use descriptive names ending in "Error" or "Exception"
• Include helpful error messages
• Consider adding custom attributes for additional context
• Create exception hierarchies for related errors
Custom exceptions make your code more maintainable and help other developers
(including future you) understand what can go wrong and how to handle it.