Error Handling with Flask Tutorial




Just like with any program, you will want to handle errors in your web application. By default, browsers handle your errors, but their default handling can be exceptionally ugly.

Besides general ugliness, the errors leave the user with fairly bad information, and, most importantly, no further call to action. Take a 404, for example. When you get a 404, it means the page you were trying to load just simply doesn't exist. The default 404 error gives no navigation back to where the user came from, and it is just a very unfriendly looking error. It almost certainly ruins the mood.

You've probably used a few websites and noticed that many websites appear to have custom errors like 404s that have various pictures. Try Google's 404 error by going to something like google.com/sfassfaa. A nice subtle robot that helps to lighten the mood when someone finds themselves on an error. Flask is no exception to allowing for custom errors. Not only can we handle things like HTTP 500, or 404 errors, but we can still also use the typical try/except syntax to handle other errors logically.

First, let's consider a simple 404, or "page not found" error. A 404 is very specific, and luckily handling this error is built into the Flask framework. First you just need a 404 function in the init file, then you can make a 404 template. You can have that 404 template extending your header, this way all of your typical CSS remains, your navbar will be there, and the general "feel" of the error will be a bit better.

from flask import Flask, render_template, flash
from content_management import Content

TOPIC_DICT = Content()

app = Flask(__name__)

@app.route('/')
def homepage():
    return render_template("main.html")

@app.route('/dashboard/')
def dashboard():
    return render_template("dashboard.html", TOPIC_DICT = TOPIC_DICT)

@app.errorhandler(404)
def page_not_found(e):
    return render_template("404.html")

if __name__ == "__main__":
    app.run()
		
File: __init__.py, server location: /var/www/PythonProgramming/PythonProgramming/__init__.py

Here, the only change is the page_not_found function.

Notice how this function is called by the wrapper above it. app.errorhandler is part of Flask, then the 404 is the specific error that we're looking to handle with whatever function we're wrapping.

In our case, we wrap the page_not_found function, using the actual error, e, as the parameter. Now, we just use a typical render_template function to render a 404.html template. That template doesn't exist yet, so let's make that.

{% extends "header.html" %}

{% block body %}

<p>Woops, that page doesn't exist! (404)</p>

{% endblock %}
		
File: 404.html, server location: /var/www/PythonProgramming/PythonProgramming/templates/404.html

Simple example, but even this tiny bit of code is a vast improvement over the default.

How about other errors? Let's cause what would normally be an internal server error and see if we can handle that.

from flask import Flask, render_template
from content_management import Content

TOPIC_DICT = Content()

app = Flask(__name__)

@app.route('/')
def homepage():
    return render_template("main.html")

@app.route('/dashboard/')
def dashboard():
    return render_template("dashboard.html", TOPIC_DICT = TOPIC_DICT)

@app.route('/slashboard/')
def slashboard():
    return render_template("dashboard.html", TOPIC_DICT = shamwow)


@app.errorhandler(404)
def page_not_found(e):
    return render_template("404.html")

if __name__ == "__main__":
    app.run()
		
File: __init__.py, server location: /var/www/PythonProgramming/PythonProgramming/__init__.py

Now we've got a new function that we're calling "slashboard." We just copy and pasted the dashboard function, changing the url and the function name. Don't forget to change the function name, or your internal server error will be for a totally different reason. It is easy to copy and paste functions to save time, but to also forget to actually change the function's name.

Instead of TOPIC_DICT = TOPIC_DICT, which is acceptable, we're going to say TOPIC_DICT = shamwow, where "shamwow" is a non-existent variable!

This could get ugly!

Save the code, restart apache, and you should find that you're getting a nasty error. Boo. So, what we can do is modify this slashboard function a bit:

@app.route('/slashboard/')
def slashboard():
    try:
        return render_template("dashboard.html", TOPIC_DICT = shamwow)
    except Exception as e:
	    return(str(e))
		

So here we're using the traditional try/except logic that is a part of Python. If the try doesn't work, then we're catching all errors to the except statement, where we are returning the error in plain text.

Great, we caught the error, only we just replaced a very ugly message with a slightly less ugly, but still ugly, message. Simple enough though, you can probably already surmise the solution:

@app.route('/slashboard/')
def slashboard():
    try:
        return render_template("dashboard.html", TOPIC_DICT = shamwow)
    except Exception as e:
	    return render_template("500.html", error = str(e))
		

So now we have a new file that we're referencing, 500.html. We pass one variable through, and that is the error.

Now we just need this 500.html page:

{% extends "header.html" %}

{% block body %}

<p>O dear, we got an error: {{ error }}</p>

{% endblock %}
		

The 500.html page is basically the same as the 404 page in simplicity, we just have the specific error that occurred as well.

Alright, I think we have had our fill of errors. Let's move on to a new topic: Flask Flashing!


There exists 1 challenge(s) for this tutorial. for access to these, video downloads, and no ads.


There exists 4 quiz/question(s) for this tutorial. for access to these, video downloads, and no ads.

The next tutorial:





  • Introduction to Practical Flask
  • Basic Flask Website tutorial
  • Flask with Bootstrap and Jinja Templating
  • Starting our Website home page with Flask Tutorial
  • Improving the Home Page Flask Tutorial
  • Finishing the Home Page Flask Tutorial
  • Dynamic User Dashboard Flask Tutorial
  • Content Management Beginnings Flask Tutorial
  • Error Handling with Flask Tutorial
  • Flask Flash function Tutorial
  • Users with Flask intro Tutorial
  • Handling POST and GET Requests with Flask Tutorial
  • Creating MySQL database and table Flask Tutorial
  • Connecting to MySQL database with MySQLdb Flask Tutorial
  • User Registration Form Flask Tutorial
  • Flask Registration Code Tutorial
  • Finishing User Registration Flask Tutorial
  • Password Hashing with Flask Tutorial
  • Flask User Login System Tutorial
  • Decorators - Login_Required pages Flask Tutorial
  • Dynamic user-based content Flask Tutorial
  • More on Content Management Flask Tutorial
  • Flask CMS Concluded Flask Tutorial
  • The Crontab Flask Tutorial
  • Flask SEO Tutorial
  • Flask Includes Tutorial
  • Jinja Templating Tutorial
  • Flask URL Converters Tutorial
  • Flask-Mail Tutorial for email with Flask
  • Return Files with Flask send_file Tutorial
  • Protected Directories with Flask Tutorial
  • jQuery with Flask Tutorial
  • Pygal SVG graphs with Flask Tutorial
  • PayPal with Flask Web Development Tutorial
  • Securing your Flask website with SSL for HTTPS using Lets Encrypt