Home Articles Categories Series
Pythonise Just now

Flask error handling | Learning Flask Ep. 18

Manually throwing errors, creating custom error handlers and rendering error templates


Article Posted on by in Flask
Julian Nash · 9 months ago in Flask

In a perfect world, our applications would never have errors and our users would use our application just as we intended, however it's not a perfect world and there will be bugs in our code and users will always be unpredictable!

Catching and handling errors ensures our users aren't confused when something goes wrong, also giving them a way to get home or back to the content.

Flask provides us with a simple way to throw and catch errors, along with displaying a custom HTML template for each error. When an HTTP error is raised, for example a 404 Not Found or 500 Internal Server Error, we can catch it, handle it and return something relevant to the exception.

Throwing errors

There may be times when you need to manually throw an error, for example if an unauthenticated user was trying to access a protected route or if a certain request method isn't allowed.

Flask provides us with the abort() function, to which we can supply the HTTP status code related to the error.

We need to import it from Flask:

from flask import abort

To use abort, simply call it and pass in the HTTP status code:

abort(404)  # Not found
abort(405)  # Method Not allowed
abort(500)  # Internal Server Error

If a user encounters the abort function, the error will trigger and the browser will display its default page/text for that error (Which normally look quite ugly)

A better solution is to setup an handler to let us decide what happens when one of these errors are encountered.

Custom error handlers

Just as we can throw errors on demand, we can handle them using the errorhandler() decorator and attaching it to our app instance.

The syntax for a custom error handler:

@app.errorhandler(STATUS_CODE)
def function_name(error):

    # Do something here..
    # Log the error..
    # Send en email..
    # Etc ..

    return render_template("handler.html"), STATUS_CODE

For example, an error handler for a 403 Forbidden status code:

@app.errorhandler(403)
def forbidden(e):
    return render_template("error_handlers/forbidden.html"), 403

Not found 404:

from flask import request

@app.errorhandler(404)
def page_not_found(e):

    app.logger.info(f"Page not found: {request.url}")

    return render_template("error_handlers/404.html"), 404

Server error 500:

from flask import request

@app.errorhandler(500)
def server_error(e):

    email_admin(message="Server error", url=request.url, error=e)

    app.logger.error(f"Server error: {request.url}")

    return render_template("error_handlers/500.html"), 500

Error templates

Default browser error pages aren't pretty:

Browser default 404 page

A better looking example of a 404 page from the Mozilla developer site:

Mozilla 404 page

Just as you would normally return a template in a route using render_template() and passing it an HTML file, we've done the same in our custom error handlers.

We've created our error HTML files and placed them in a directory called error_handlers, giving each HTML file the name corresponding to the error which we then call with render_template, passing it the path to the relevant handler file.

Wrapping up

Throwing strategic errors is as simple as calling abort() and passing it an HTTP status code.

Handling errors and creating custom error pages is also simple with @app.errorhandler(STATUS) and writing a function to handle the error and return a relevant response.

Last modified · 28 Feb 2019
Did you find this article useful?
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
Contents
Loading...