Python Web Development With Flask - Part 7

in STEMGeeks2 months ago

Custom Error Pages

This is the 19th article in our series of getting started coding with Python, looking directly at web development using Flask. Our web app looks completely different to when it started and the we have been doing a lot to make sure the structure is set up in a way that is understandable and easy to develop further.

In this article we are going to add error pages to our project. You may be thinking, why or "don't we already have error pages", yes, but we are going to set up the error pages to no longer be the default web server error pages. Instead we are going to try and catch any errors that might arise and deliver the user to a web page that has the same style as the rest of our web app and also try and give the user some useful information.

If you would like to revert back to the previous articles, head over to our GitHub page where you will find all the code as well as links to all the other articles in the series:
https://github.com/vincesesto/python_study

If you've been following along so far with this project, you will not have to perform the following steps, but if you are new to the series, run the following set of commands in your working directory to get the "Flasking" web app up and running before we move further on with this project:

# Clone the repository:
git clone https://github.com/vincesesto/python_study.git

# Move into the root directory:
cd article_18/

# Create a virtual environment named venv
python3 -m venv venv

# Activate the virtual environment
source venv/bin/activate

# Install all of the requirements:
pip3 install -r requirements.txt

# Export where the app.py script is
export FLASK_APP = "app.py"

# Verify the flask web server runs without errors
flask run

# Open a web browser and enter the following 
# URL to see the index page of the Flasking app
http://127.0.0.1:5000/

Creating Error Pages For Our Web App


We will first start with creating a template for capturing 404 and 405 errors in our application. A 404 error is usually presented to the user when they have navigated to a page that is not found on a specific web site. A 405 error is when the user has tried to access a method in our URL that is not allowed. For example, if you perform a POST method on a page that does not have access to perform a method like this.

We will start by creating our template first, so log back into your working environment and run the following command to create the 404 template.

cp projects/users/templates/users/index.html templates/404.html

We have used the index.html template to start off our code for the 404.html template. You will need to open the file with your text editor and make it look like the following code.

{% extends "base.html" %}

{% block content %}
<h1 class="container">Page Not Found (404)</h1>
<div class="container">
  <h4>What you were looking for is just not there!</h4>
  <h4><a href="{{ url_for('users.index') }}">Flasking App</a></h4>
</div>
{% endblock %}

As you can see we are using the base.html template as we have with the rest of our code as it will present details to the user just like the rest of the pages in the web app.

Create the 405 template with the following command:

cp templates/404.html templates/405.html

Open the 405.html template with your text editor and make sure it looks like the following code to give the user specific information relevant to the error.

{% extends "base.html" %}

{% block content %}
<h1 class="container">Method Not Allowed (405)</h1>
<div class="container">
  <h4>The requested method is not supported by this resource!</h4>
  <h4><a href="{{ url_for('users.index') }}">Flasking App</a></h4>
</div>
{% endblock %}

We have set up our template but we need to let the app know when to serve the pages to the user. We can do this pretty easily in the app.py file. The application we have set up can use the errorhandler() function to look for the specific 404 and 405 errors and then set up a route to be servered to the user when they receive that error.

Open the app.py file with your text editor and make sure it looks like the following code. You will notice towards the bottom of the page, we have added two specific functions for 404 and 405 errors:

from flask import Flask, render_template, request, session, redirect, url_for

app = Flask(__name__)

app.secret_key = '\x98)\x861hX[\xf1\xc5Z\[email protected]\xe7[K\xfe\xb5\xc7~\xb0\x99\x1e\x8f\xfem\xa6F\xc1&'

# Import the blueprints
from projects.runs import runs_blueprint
from projects.users import users_blueprint

# Register the blueprints
app.register_blueprint(runs_blueprint)
app.register_blueprint(users_blueprint, url_prefix='/users')

# Error Pages
@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

@app.errorhandler(405)
def method_not_allowed(e):
    return render_template('405.html'),

That's about all we need to do to get this working. If you start up the development web server again with the "flask run" command.

Open your web browser and look for a page that should not exist, like the following example:
http://127.0.0.1:5000/does_this_page_exist

You should now be presented with an error page with a little more useful information that what would normally be presented. It will have all the relevant styles used by our current app and hopefully present some more useful information to the user.

Creating A 403 Error Page


A 403 error is a little different as it is relevant to a user not having access to a specific page like an administrator or something similar. We will set one up below as if we had a user admin page that only can be accessed by an administrator. Here we would set up the template and routes in the blueprints for users.

Start by getting back into your working environment and make a copy of the 405.html page and place it in the users blueprints templates directory:

cp /templates/405.html projects/users/templates/users/403.html

Open the file with your text editor and make sure it has a relevant error, like the code below:

{% extends "base.html" %}

{% block content %}
<h1 class="container">Forbidden (403)</h1>
<div class="container">
  <h4>You don't have permission to access the requested resource!</h4>
  <h4><a href="{{ url_for('users.index') }}">Flasking App</a></h4>
</div>
{% endblock %}

Add the route to the users blueprint but you need to make it specific to the route location. You will need to have your routes look like the code below where we add a route for the admin page and then deliver an error to the user:

from flask import Flask, render_template, request, session, redirect, url_for, flash, abort
from . import users_blueprint

app = Flask(__name__)

@users_blueprint.route('/')
def index():
    return render_template('users/index.html')

@users_blueprint.route('/about')
def about():
    return render_template('users/about.html', version='0.0.1')

@users_blueprint.errorhandler(403)
def page_forbidden(e):
    return render_template('users/403.html'), 403

@users_blueprint.route('/admin')
def admin():
    abort(403)

Once again we can test the app in the development web server again and if all goes to plan, if we now try to access the /admin page, we will get our 403 error.

Found this post useful? Kindly tap the up vote button below! :)

About The Author
I am a DevOps Engineer, Endurance Athlete and Author. As a DevOps Engineer I specialize in Linux and Open Source Applications. Particularly interested in Search Marketing and Analytic’s, and is currently developing my skills in devops, continuous integration, security, and development(Python).

Posted with STEMGeeks

Sort:  

I can see lots of action in your GitHub page and for any development its very important. I don't know Python coding so I cant contribute from the technical side.

@alokkumar121 it means a lot that you even took the time to look. Thanks so much and it's all about developing my own abilities for the future. Thanks so much.