To define your own exceptions correctly, there are a few best practices that you should follow:
Define a base class inheriting from Exception
. This will allow to easily catch any exceptions related to the project:
class MyProjectError(Exception):
"""A base class for MyProject exceptions."""
Organizing the exception classes in a separate module (e.g. exceptions.py
) is generally a good idea.
To create a specific exception, subclass the base exception class.
To add support for extra argument(s) to a custom exception, define a custom __init__()
method with a variable number of arguments. Call the base class's __init__()
, passing any positional arguments to it (remember that BaseException
/Exception
expect any number of positional arguments):
class CustomError(MyProjectError):
def __init__(self, *args, **kwargs):
super().__init__(*args)
self.foo = kwargs.get('foo')
To raise such exception with an extra argument you can use:
raise CustomError('Something bad happened', foo='foo')
This design adheres to the Liskov substitution principle, since you can replace an instance of a base exception class with an instance of a derived exception class. Also, it allows you to create an instance of a derived class with the same parameters as the parent.