Why and how custom exceptions lead to cleaner, better code

Clean up your code by creating your own custom exceptions

Why and how custom exceptions lead to cleaner, better code
(image by Sarah Kilian on Unsplash)

There’s a big difference between exceptions and errors; exceptions are deliberate while errors are unexpected. This article focusses on creating your own exceptiosn and how using them cleans up your code, resulting in a less error-prone program, a better flow and faster debugging. Let’s code!


The dirty way

To demonstrate how the custom exceptions work we’ll imagine we’re building a website. We focus on improving the log-in function of the website that currently looks like this:

It’s a fairly easy function:

  1. we pass an email and password
  2. check if an account exists associated with the email address. Show popup and redirect to /register page if not
  3. check if the credentials are valid. Valid: show popup. Invalid: show popup and redirect

You call the function like:login_dirty(email='mike@bmail.com', password='my_pa$$word')

A complete guide to using environment variables and files with Docker and Compose
Keep your containers secure and flexible with this easy tutorial

What’s wrong with the current login function?

The problem with the login function is that it is dirty. What I mean with this is that it is responsible for things it shouldn’t be responsible for. I usually separate my project in two:

  1. clean code
  2. dirty code

To me, the difference is that clean code is unaware of your business logic. You can take ‘clean’ functions from one project and use them in a totally different one. Dirty code, however, contains business logic; for example what happens when you cannot log in. Do you get redirected? Is a popup displayed? Let’s make our login function nice and clean by removing all business logic with custom exceptions.

6 Steps to Make this Pandas Dataframe Operation 100 Times Faster
Cython for Data Science: Combine Pandas with Cython for an incredible speed improvement

The clean way

We want a login-function that is unburdened by any business logic. If it cannot log in a user we just have to signal that it’s not possible; some other part of our code (the dirty part) can decide what to do with it.

When you look at our function two thing can go wrong:

  1. The email address is unknown (i.e. the user is not registered)
  2. The email-password combination is incorrect

These two things are the exceptions that prevent a successful login: First we’ll write some code that allows us to raise these exceptions. Then we’ll clean up our function and the way the function is called.

Why Python is so slow and how to speed it up
Take a look under the hood to see where Python’s bottlenecks lie

Creating custom exceptions

Creating a custom exception is easier than you think:

As you see we create a new class that just inherits from the Exception class. Then, in order to have a nice message for fellow developers, we only override the __str__ method.

We can also pass arguments to our exception like in the UserNotFoundException. Here we do the exact same thing as before, only we need to store the email as an attribute using the __init__ method.

Destroying Duck Hunt with OpenCV — image analysis for beginners
Write code that will beat every Duck Hunt high score

2. Cleaning up the login function

Check out how nice and clean this function looks using the new exceptions:

In addition to looking much nicer the function is more clean and pure; it is only responsible for logging in, if doesn’t have to know anything about redirecting and popups. This kind of logic should be limited to a few places in your project and shouldn’t be littered throughout. Custom exceptions help a great deal with this.

Docker for absolute beginners — what is Docker and how to use it (+ examples)
Manage your infrastructure in the same ways you manage your applications

3. Calling our login

In our main.py file we can now call the login function like this:

As you see it’s really clear what happens when we cannot log in. The main benefit is that if you decide at a later time that invalid credentials should also be redirected; there are not many places to search since your business logic isn’t littered throughout your entire project.

Virtual environments for absolute beginners — what is it and how to create one (+ examples)
A deep dive into Python virtual environments, pip and avoiding entangled dependencies

Conclusion

In this article I hope to have shown why to use custom exceptions: to help keep an overview on the business logic of your code, they help to keep your functions pure/clean and debug-able. Your own exceptions are pretty easy to create and use throughout your project.

I hope everything was as clear as I hope it to be but if this is not the case please let me know what I can do to clarify further. In the meantime, check out my other articles on all kinds of programming-related topics like these:

Happy coding!

— Mike

P.S: like what I’m doing? Follow me!

Join Medium with my referral link - Mike Huls
Read every story from Mike Huls (and thousands of other writers on Medium). Your membership fee directly supports Mike…