Ultimately, all non-exit exceptions in Python are subclasses of the builtin Exception
class.
#The following examples shows that all exceptions are derived from the Exception class
print(issubclass(ValueError, Exception))
print(issubclass(IndexError, Exception))
print(issubclass(TypeError, Exception))
print(issubclass(KeyError, Exception))
We can define our own custom exceptions by creating a class derived from the Exception
class.
#Define a custom exception
class customClass(Exception):
#statements
After a class inherits from the Exception
class, it immediately becomes an Exception just like the builtin ones. You can raise it normally using the raise
statement and you can also handle it using the try-except
blocks,.
class ExampleException(Exception):
pass
raise ExampleException
Customizing User-defined Exceptions
We can customize the custom exceptions to suit our needs. However, you will need a basic understanding of the fundamental concepts of object oriented programming in order to follow through.
By defining the __init__()
method for our custom exception class, we can be able to pass custom arguments to the exception.As shown below:
class NotEligibleException(Exception):
#Define the class c
def __init__(self, age, *args, **kwargs):
self.age = age
super().__init__(*args, **kwargs)
self.message = f"age {age} is not eligible for voting"
def __str__(self):
return self.message
age = 10
if age < 18:
raise NotEligibleException(age)
In the above example, we defined the NotEligibleException
class which is meant to be raised if the target age is not eligible for voting. The exception takes an age parameter which is used in customizing the display message.
We can literally override any valid magic/dunder method for the custom exception. When we do this we can effectively define the behavior of our custom class to suit the program's need.
Inheriting from standard Exceptions
Custom exception can inherit from other standard exception classes rather than inheriting directly from the base Exception
class. This enables custom exceptions to take advantage of existing behavior from other standard exceptions.
class NetworkError(RuntimeError):
def __init__(self, message, *args, **kwargs):
super().__init__(*args, **kwargs)
self.message = message
def __str__(self):
return self.message
try:
raise NetworkError("An error accurred.")
except NetworkError as e:
print(e.message)