Flask error handling | Learning Flask Ep. 18
Manually throwing errors, creating custom error handlers and rendering error templates
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:
A better looking example of a 404 page from the Mozilla developer site:
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
Source : .