A minimalist guide to handling API errors in Flask

Given a task to build a REST/JSON service in Flask, there arises the need to format exceptions from the default werkzueg’s text/html format to a more nicer, API friendly format; JSON in our case.

Although This Flask snipet post by Pavel Repin provides an easier way to do it, much has changed from when the snippet was first posted, this change in flask, for one and the now added support for python3.6, make parts of the code unusable.

I modified the snippet and here’s an improved way to do it

from flask import Flask, jsonify
from werkzeug.exceptions import default_exceptions
from werkzeug.exceptions import HTTPException

__all__ = ['make_json_app']

def make_json_app(import_name, **kwargs):
    """
    Creates a JSON-oriented Flask app.

    All error responses that you don't specifically
    manage yourself will have application/json content
    type, and will contain JSON like this (just an example):
    {
        "error": "Method Not Allowed",
        "error_description": "werkzeug.exceptions.MethodNotAllowed: 405 Method Not Allowed: The method is not allowed for the requested URL.",
        "status_code": 405
    }
    """
    def make_json_error(e):
        code, err = None, None
        code = (e.code if isinstance(e, HTTPException) else 500)
        err = str(e)
        desc = traceback.format_exception_only(type(e), e)[0].strip())
        return jsonify({
            'status_code': code,
            'error_description': desc,
            'error': err
        })
        
    app = Flask(import_name, **kwargs)

    for code in default_exceptions.iterkeys():
        app.error_handler_spec[None][code] = make_json_error

    return app

This improved functionality catches all default exceptions and transforms them into nicer formatted JSON exceptions.

The snippet however, gets a little bit opinionated on the error format, feel free to format your errors as you want. HINT: Try make them as descriptive as possible.

Have fun coding :slightly_smiling_face: