Python – considered best practice for custom exception classes

exceptionspython

Python has many strong conventions but I'm unclear on how best to manage exceptions for my module. I know it's generally good practice to define a custom exception for your module. E.g.:

class MyError(Exception):
    pass

However, what I'm not clear on is how specific exception classes should get? Should each code path that results in a failure have its own exception class? Or is it better to use only a few? A hierarchy of exceptions where each "leaf" exception inherits from a slightly more generic parent exception would allow the module's users to decide how fine-grained their exception handling is but I can see how that could become convoluted to deal with.

I know some modules use error codes to distinguish between different errors that use the same class, which is used something like this:

try:
    mymodule.do_something()
except mymodule.MyError as error:
    if error.code == mymodule.SPECIFIC_ERROR_CODE:
        handle_error()
    else:
        raise

But that feels wrong to me unless you're purposefully mimicking another library.

Is there an ideal way to handle this? Or is this question too dependent on the situation for a generic best practice?

Best Answer

If the library is only used by your own code or in your own organization, then YAGNI applies. You should only make only as many exception sub-classes as you need to handle separately. If two different error conditions are handled in the same way (which may include not handling but termination the application!), then you only need a single exception class.

In other words, only create as many subclasses as you actually need.

I don't really like the idea of error codes. It just introduces an additional way to signal errors which is not supported as nicely by the language (as your code example shows). If you actually need to handle the different error codes differently you might as well make separate exception classes.

Related Topic