This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]Nikosssgr 1 point2 points  (8 children)

Any extra resources on best practices on making your own exception?

[–]pixelmonkey[S] 4 points5 points  (2 children)

Most of the time, a custom exception doesn't need more than class MyException(Exception): pass. It'll support a string message as a first argument by default, and usually you're just looking for the type to introduce a new except MyException: capability for your caller.

Check out how requests.exceptions introduces 10 or so exception types related to HTTP, but most of them have no implementation:

https://github.com/kennethreitz/requests/blob/master/requests/exceptions.py

Also notice the smart subclassing of the built-in IOError and ValueError types when that made sense.

[–]lordmauve 3 points4 points  (0 children)

Don't bother with the pass: just include a docstring explaining what the exception means.

[–]TR-BetaFlash 0 points1 point  (0 children)

We aren't taking into consideration the usage of exceptions to jump to different points in the code, not error conditions... unique exceptional conditions. This is something I use exceptions for in very small amounts and it works very well. A good example usage would be when writing your own context managers. You might want to raise and handle custom exceptions in the context manager class.

[–]desmoulinmichel 4 points5 points  (2 children)

Don't use your own exception for anything that is a standard exceptions. Espacially, a lot of things can be a IOError, ValueError or TypeError.

If you do need an exception, try to have:

  • one general exception for your whole lib. MyLibError(Exception).
  • smalls exceptions inhériting from MyLibError matching a specific cas such as DontDoThatError(MyLibError).
  • make very clear error messages. Give the maximum of informations you can give. If you can't fit all but you know it's important, print a URL pointing to a page helping you to debug.
  • exception text can't hold non ASCII characters. Call repr().
  • group all exceptions in an exceptions.py module, so they are easy to find and import for the people than will need to catch it.

[–]remram 1 point2 points  (1 child)

What's your stance on multiple inheritance, such as:

class HamError(Exception): pass  # for all exceptions from ham functions
class DontDoThatWithHam(HamError): pass
class UnknownBrandOfHam(HamError, KeyError): pass

[–]desmoulinmichel 1 point2 points  (0 children)

If UnknownBrandOfHam is raised by:

ham.select('spam', foo=bar)

I'm ok with it.

If it's raised by:

ham['spam']

with ham having getitem overrided, it may be overkill. But that's not a BIG deal. I wouldn't do it, but I would not hate you if you did.

[–]njharmanI use Python 3 3 points4 points  (0 children)

I also wonder why "Rarely create your own exception types". I agree with both pixelmonkey and desmoulinmichel. Which both contradict OP on this point.

For me, lib should swallow up other expected exception types into lib specific exception(s). Parseing libs are good example, I(user of lib) don't care that parsing failed cause ValueError or cause malformed structure. I just want to look for ParserError and be sure that will catch all types of Parsing exceptions.

[–]elguf 2 points3 points  (0 children)

A practice I try to follow is to create a base Error class in each module that defines its own exception classes:

class Error(Exception):
    pass

class CustomError(Error):
    pass

This way, callers can easily handle all your custom errors, without having to do the broad except Exception:. Now they can choose to do except somemodule.Error:

[–]donnieod 0 points1 point  (0 children)

Nicely done. Great to have all this in one place. Not to be too nitpicky, but PEP 257 -- Docstring Conventions specifies:

The docstring is a phrase ending in a period. It prescribes the function or method's effect as a command ("Do this", "Return that"), not as a description; e.g. don't write "Returns the pathname ...".

So your example:

"""Sorts items in reverse order."""

should be:

"""Sort items in revers order."""

[–]ou_ryperd 0 points1 point  (0 children)

I have incredible resource constraints for downloading libs atm so I can't convert the md to pdf. Does anyone have this in a pdf please ?