3

I'm using Connexion (https://github.com/zalando/connexion) to make sure my openapi-specification is well-followed and to have easy integration points to connect my routes to the underlying functions.

In any case, the default error responses from Connexion are json responses following the Problem Details for HTTP APIs RFC. That is the following format, e.g.:

{
    "detail": "None is not of type 'object'",
    "status": 404,
    "title": "BadRequest",
    "type": "about:blank"
}

However, I would like to change the format of all errors sent to something like:

{
    error: {
        code: 400,
        message: 'BadRequest',
        detail: 'ID unknown'
        innererror: {...}
    }
}

I can not find any way to intercept every error to change the format of what is returned. I know I can extend the connection.exception.ProblemException class and add a dict to the extparameter in its constructor, but for any 400 error for example, I can't intercept it.

So, I know that it is possible to add error handlers for specific error codes, e.g.:

app.add_error_handler(404, error.normalize)
app.add_error_handler(400, error.normalize)

However, for the 404 handler I manage to successfully intercept the error. But for the 400 (e.g. a json validation error) - the interception does not work.

How can I intercept each and every error that is sent from Connexion and change the json format, even if it is just to extend it like:

{
    "detail": "Could not find page",
    "error": {
        "code": 404,
        "message": "Could not find requested document."
    },
    "status": 404,
    "title": "NotFound",
    "type": "about:blank"
}

I use Connexion, with a 'tornado' server.

Thanks in advance. Tom

Community
  • 1
  • 1
Tom P.
  • 390
  • 3
  • 12

1 Answers1

3

With the latest version (connexion==2.5.1) this works for me:

from connexion import ProblemException
[...]

connexion_app.add_error_handler(400, render_http_exception)
connexion_app.add_error_handler(404, render_http_exception)
connexion_app.add_error_handler(ProblemException, render_problem_exception)

My exception handling functions:

from flask import jsonify


def render_http_exception(error):

    resp = {
        'error': {
            'status': error.name,
            'code': error.code,
            'message': error.description,
        }
    }

    return jsonify(resp), error.code


def render_problem_exception(error):

    resp = {
        'error': {
            'status': error.title,
            'code': error.status,
            'message': error.detail,
        }
    }

    return jsonify(resp), error.status

You can easily change it to your format.

aswyx
  • 345
  • 1
  • 5
  • 14