TIL: Creating Custom Python Exceptions

Honestly this is something that I learned many many months back but evidently never wrote about (I’m not really sure why). I had to do a small side project at work and I needed to revisit how this was done. Thankfully I already had a project completed that I could steal off of!

So the goal here is to try to make the transition away from returning something like a failed stated from a method you provide. Let’s say that I’ve created a package that will reverse the string that you give it. Rather than doing some checks to see whether or not what was given to you was a string and then passing back some sort of failure that your user then has to write logic for, you can instead create a custom exception to be thrown.

This was a big issue for me back at my old job. I had a terrible habit of returning back the strangest response messages if something were to go wrong. Sometimes returning back a false, sometimes an entire payload of what went wrong and blah blah blah.

It was much later on (at the start of this year) when I found that the better way of handling this was through throwing exceptions. And when making your own packages, it was recommended to just create your own.

So that’s what we’re going to focus on here: how can I create my own exception?

I don’t remember the specifics behind all of this (it’s been awhile since I python’d), but here’s how I went about solving the issue.

To begin, you start by defining a class that will implement an exception. This is going to be our top level exception from which all of our other exceptions are build:

class RandomUserError(Exception):
   def __init__(self, message):
       super(RandomUserError, self).__init__(message)

I don’t remember what the super stuff is for, but it DOES require a message when calling. That means that when it’s time for you to raise the exception in your code, you can simply do:

raise RandomUserError("Something went wrong!")

and that message will be passed back with the exception.

Now, if you want to create other exceptions that build off of this one, you can implement additional ones using this base exception. For example, if I wanted to create another one that would allow me to, once again, define what I wanted as my message, all I would have to do is this:

class resultsError(RandomUserError):
   """When there's an error with results value"""

And this can be called in just the same way:

raise resultsError("Your result is bad")

If you already know what your exception is going to be ahead of time (you know the text error), you can code it into the exception itself:

class passwordLengthError(RandomUserError):
   """When there's an error with the pass_length value"""
   def __init__(self):
       super(passwordLengthError, self).__init__(message="Incorrect pass_length format. Should be either a single number or range of numbers from 1-64.")

And when raised, it will return the message that is set by the exception. Super easy.

I’m not sure if this is the absolute best way to do this, but it has been working for me, and seems to be a lot better than returning back false values randomly.