📚 Book Highlights

Flask Web Development by Miguel Grinberg

Highlights of the book Flask Web Development by Miguel Grinberg
Jonathan Machado avatar picture

By Jonathan Machado

April 8, 2021


Error handling: Keeping your code DRY

You might have seen projects where common scenarios are handled in every view, for example, getting a User by ID but returning an error if it hasn't been found.

It's common to see views like these handling the "user is not found" case:

# /rest/users.py

def get_user(user_id):
    user = Users.get_or_none(Users.id == user_id))
    if not user:
        return jsonify({"error": "User not found"}), 404

    return jsonify(model_to_dict(user))

# OR alternatively:

def get_user(user_id):
    try:
        user = Users.get(Users.id == user_id))
    except Users.DoesNotExist:
        return jsonify({"error": "User not found"}), 404

    return jsonify(model_to_dict(user))

This scenario might repeat itself dozens of times throughout your codebase for similar endpoints.

However, we can create global error handlers to catch those exceptions. These handlers can be created on the app level, for all blueprints or for a specific blueprint:

# /rest/error_handlers.py

error_handler = Blueprint("error_handler", __name__)

@error_handler.app_errorhandler(DoesNotExist)
def does_not_exist(error):
    # we could log the error to Sentry here, if we want.
    return jsonify({"error": "Object not found"}), 404

app_errorhandler() creates a handler for all blueprints. We could also use errorhandler() instead which registers an error handler that becomes active for that blueprint only.

This allows our views to be fairly simple now!

# /rest/users.py

def get_user(user_id):
    user = Users.get(Users.id == user_id))
    return jsonify(model_to_dict(user))

Users.get will raise a DoesNotExist exception if no entry is found in the database, which is then handled by our does_not_exist() global error handler.


Stay in touch

Receive updates about new articles as well as curated and helpful content for web devs. No spam, unsubscribe at any time.