Send With Confidence
Partner with the email service trusted by developers and marketers for time-savings, scalability, and delivery expertise.
Time to read: 6 minutes
$ mkdir flask-error-alerts | |
$ cd flask-error-alerts | |
$ python3 -m venv venv | |
$ source venv/bin/activate | |
(venv) $ pip install flask python-dotenv sendgrid |
$ md flask-error-alerts | |
$ cd flask-error-alerts | |
$ python -m venv venv | |
$ venv\Scripts\activate | |
(venv) $ pip install flask python-dotenv sendgrid |
pip
, the Python package installer, to install the two packages that we are going to use in this project, which are:
SENDGRID_API_KEY=your-sendgrid-api-key-goes-here |
from flask import Flask | |
app = Flask(__name__) | |
@app.route("/") | |
def index(): | |
return "Helloworld!" |
$ flask run |
app.py
to throw an unhandled exception.
from flask import Flask | |
app = Flask(__name__) | |
class BigBangException(Exception): | |
pass | |
@app.route("/") | |
def index(): | |
raise BigBangException("Something bad happened here..") | |
return "Helloworld!" |
$ flask run |
import traceback | |
from flask import Flask | |
from werkzeug.exceptions import InternalServerError | |
app = Flask(__name__) | |
@app.errorhandler(InternalServerError) | |
def handle_500(e): | |
error_tb = traceback.format_exc() | |
return app.finalize_request(e, from_error_handler=True) | |
class BigBangException(Exception): | |
pass | |
@app.route("/") | |
def index(): | |
raise BigBangException("Something bad happened here..") | |
return "Helloworld!" |
Flask does have built-in error handlers (read more about that here). We use the @app.errorhandler
decorator to register a function with the Flask application. It’s quite similar to the @app.route
decorator except that it allows us to register a function that gets executed when particular types of errors occur in our application. In this case, we are paying attention to the InternalServerError
exception. This is the exception that Flask and it’s underlying utility library Werkzeug raise whenever an unhandled exception occurs.
Note: We are using Python’s built-in traceback module to retrieve the traceback information. The variable we created called error_tb
is a string that contains the traceback. This traceback is exactly the same as what we see in the terminal when the unhandled exception occurs in the Flask application. We will pass this information into our SendGrid email in the next section.
We also added a call to the app.finalize_request
method. This maintains the default behavior of our Flask application:when an unhandled exception occurs, we will still return the internal server error response to the browser.
We’re now at the point where we can set up the code to send the alert email. So let’s do that by updating app.py to contain the following:
import os | |
import traceback | |
from flask import Flask | |
from werkzeug.exceptions import InternalServerError | |
import sendgrid | |
from dotenv import load_dotenv | |
load_dotenv() | |
app = Flask(__name__) | |
sg = sendgrid.SendGridAPIClient() | |
def create_message(email_text): | |
return sendgrid.helpers.mail.Mail( | |
from_email=os.environ["FROM_EMAIL"], | |
to_emails=os.environ["TO_EMAIL"], | |
subject='[my app] unhandled exception occurred!', | |
plain_text_content=email_text, | |
) | |
@app.errorhandler(InternalServerError) | |
def handle_500(e): | |
error_tb = traceback.format_exc() | |
try: | |
resp = sg.send(create_message(error_tb)) | |
except Exception as exc: | |
print(exc.message) | |
return app.finalize_request(e, from_error_handler=True) | |
class BigBangException(Exception): | |
pass | |
@app.route("/") | |
def index(): | |
raise BigBangException("Something bad happened here..") | |
return "Helloworld!" |
create_message
which sets up a SendMail Mail
object. This object pulls in the FROM_EMAIL
and the TO_EMAIL
from the .env file. With that said we need to add the following lines into our .env file:
SENDGRID_API_KEY=your-sendgrid-api-key-goes-here | |
FROM_EMAIL=your-email-address | |
TO_EMAIL=your-email-address |
load_dotenv
function. This ensures that when our code runs, the required environment variables will be available in our application code.
sg = sendgrid.SendGridAPIClient() |
SENDGRID_API_KEY
and uses it to authenticate against the SendGrid servers. As with the other variables in our .env file, the load_dotenv
call ensures that the variable is imported into the environment of the process.
try: | |
resp = sg.send(create_message(error_tb)) | |
except Exception as exc: | |
print(exc.message) |
$ flask run |
Partner with the email service trusted by developers and marketers for time-savings, scalability, and delivery expertise.