Menu Close

Python Web Development with Flask — Error Handling

Flask is a simple web framework written in Python.

In this article, we’ll look at how to develop simple Python web apps with Flask.

Application Errors

We can add our own error handlers into our Flask app.

For example, we can write:

from flask import Flask, abort
import werkzeug
app = Flask(__name__)

@app.errorhandler(werkzeug.exceptions.BadRequest)
def handle_bad_request(e):
    return 'bad request!', 400

@app.route('/')
def hello_world():
    return abort(400)

We add a handler for handling 400 errors.

The handler is registered with the app.errorhandler decorator.

The werkzeug.exceptions.BadRequest means we’re using it to handle 400 errors.

We return a 400 error in the hello_world route function, so we should see ‘bad request!’ returned with the response.

Equivalently, we can write:

from flask import Flask, abort
import werkzeug
app = Flask(__name__)

def handle_bad_request(e):
    return 'bad request!', 400

app.register_error_handler(400, handle_bad_request)

@app.route('/')
def hello_world():
    return abort(400)

to register the error handler.

We can also register error handlers for nonstandard status codes.

To do that, we just have to make a class that extends werkzeug.exceptions.HTTPException .

For instance, we can write:

from flask import Flask, abort
import werkzeug
app = Flask(__name__)

class InsufficientStorage(werkzeug.exceptions.HTTPException):
    code = 507
    description = 'Not enough storage space.'

def handle_507(e):
    return 'Not enough storage space.', 507

app.register_error_handler(InsufficientStorage, handle_507)

@app.route('/')
def hello_world():
    raise InsufficientStorage()

to create the InsufficientStorage exception class.

We set the code and description instance variables with the status code and description respectively.

Then we call app.register_error_handler to register the error handler.

Generic Exception Handlers

We can create generic exception handlers.

For instance, we can write:

from werkzeug.exceptions import HTTPException
from flask import json
from flask import Flask, abort
app = Flask(__name__)

@app.errorhandler(HTTPException)
def handle_exception(e):
    response = e.get_response()
    response.data = json.dumps({
        "code": e.code,
        "name": e.name,
        "description": e.description,
    })
    response.content_type = "application/json"
    return response

@app.route('/')
def hello_world():
    return abort(400)

We add the handle_exception function with the app.errorhandler decorator to register the exception handler.

In the function, we create the response object from the e.get_response method.

Then we set the response.data property to set the response data.

We use json.dumps to convert the dictionary to a string.

Unhandled Exceptions

Unhandled exceptions are returned as 500 errors.

We can add a 500 error handler to catch handled and unhandled exceptions.

For example, we can write:

from werkzeug.exceptions import InternalServerError
from flask import json
from flask import Flask, abort
app = Flask(__name__)

@app.errorhandler(InternalServerError)
def handle_500(e):
    original = getattr(e, "original_exception", None)
    if original is None:
        return 'handled error'
    return 'unhandled error', 500

@app.route('/')
def hello_world():
    raise Exception()
    return 'hello'

We add the handle_500 function to handle both handled and unhandled errors.

The original variable being None means that it’s a handled error.

Otherwise, it’s an unhandled error.

Since we raised a generic exception in the hello_world function, we should see 'unhandled error' in the response.

Conclusion

We can catch and handle errors raised in Flask apps.

Posted in flask, Python