Error handling for Django applications using email

When you deploy any application to production, there is always this inherent anxiety - what would happen if there are unhandled exceptions?

When an unhandled exception occurs in your Django application, it leads to an internal server error and returns a 500 error code to the client. Completely avoiding such exceptions is usually not possible.

What you can do though is have eyes on your application. A mechanism to get alerted whenever such an exception occurs so that you can take action immediately. 

There are several ways to do this. You could use a tool like Sentry which gives you a very comprehensive stack trace along with the offending request that caused the error. 

However, the simplest way to do this is to send an email to yourself with the stack trace of the exception.

Fortunately, Django already thought of this and has a pretty straightforward mechanism to email yourself with exceptions using the ADMINS setting. Whenever an error occurs, if DEBUG is set to False, Django will email all the IDs mentioned in ADMINS.

Format of the error email

Before we get into what settings need to be configured to send the email, let us look at what the email looks like.

I am currently building an app called DailyHabits and I will emulate an error by adding a line of code that divides a number by zero.



This will make sure that the server throws an error when this code is invoked. I will then fire an API call that invokes this particular code and this is the email that I received when the error occurred.





As you can see, the email contains a full stack trace of the exception which you can use to find the exact line in your codebase which is causing it.

This is the simplest form of error handling and is quite nifty because you most likely receive email notifications on your phone and therefore you will be immediately notified when there is an error in your application.

You now have eyes on your application's health.

Using gmail to send error emails

In order to send the email, there are a few settings that you need to configure in settings.py. You can send the emails using your own gmail account by setting up the smtp credentials as shown below.



However, for this to work you would have to allow gmail to let you access it via a non gmail app. You can do this in the security settings





This method is not recommended as you can see from the “not recommended” text in the above image. It leads to security vulnerabilities, not to mention the fact that you have your gmail account password somewhere in your codebase.

You can protect the password by not using it directly in your codebase and setting it up in the environment variables instead. 

You can further strengthen security by creating a new gmail account whose sole purpose will be for sending error emails. This way, even if this account gets compromised it won't really affect you much. It is more of a burner email.

If you are wondering if it’s worth going through so many hoops and leave yourself open to security issues, you are right. Which is why I recommend using mailgun instead of your personal gmail account to send error emails.

Using mailgun to send error emails

I recommend mailgun for three reasons:

  1. They have comprehensive APIs that let you send all kinds of emails.
  2. You can send upto 6k emails a month in their free plan.
  3. It is relatively easy to set up.

To send emails using mailgun, signup for an account on mailgun, and create a new domain. As you can see below, I have already set up a domain called dailyhabits.xyz which I own.



The process will involve setting up a few DNS records in your domain provider to prove to mailgun that you own the domain.

If you need further help setting this up, check out this really good tutorial.

Once this process is complete, you can create a new SMTP user for sending error emails.





After a credential is created, you will be allowed to copy the password to the clipboard post which the password will no longer be available to you unless you explicitly reset it. 

Make sure you copy the password and save it somewhere.




The smtp credentials to configure in settings.py will be as follows:



And that’s it. We are all set up.

Closing notes

Error handling requires two things.

  1. Getting notified when there is an error in your server.
  2. A way to trace the line of code which is causing the error.

Both of these requirements get solved with this simple mechanism of sending an email to yourself.

It functions as a notification that is hard to miss since email notifications are received on the phone and the stack trace given inside the email will help you find the offending line of code quite easily.

You can now rest easy knowing that your application is performing well and in case it is not, you will find out immediately.