connexion icon indicating copy to clipboard operation
connexion copied to clipboard

Illegally formatted JSON leads to JSONDecodeError when used with encoding section

Open thiagobell opened this issue 4 years ago • 0 comments

Description

I need to define an endpoint with a multipart/form-data content type taking a few parameters. One of them is a JSON representation of a document. However, when an invalid JSON string is provided in a request, e.g. a string missing quotes or empty, connexion tries do deserialize it but fails and the json library raises JSONDecodeError.

Expected behaviour

If an invalid JSON is provided I expect the response to the client to be something like this: { "detail": "'doc_json' is not of type 'object' - 'document_json'", "status": 400, "title": "Bad Request", "type": "about:blank" }

Actual behaviour

However, the JSONDecodeError exception is not catched by connexion leading to a server error and this response to the client:

{ "detail": "The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.", "status": 500, "title": "Internal Server Error", "type": "about:blank" }

Steps to reproduce

I set up the server like this:

import connexion

# Create the application instance
app = connexion.App(__name__, specification_dir='./')

# Read the swagger.yml file to configure the endpoints
app.add_api('swagger.yml', strict_validation=True, validate_responses=True)

# If we're running in stand alone mode, run the application
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001)

The endpoint method is defined as:

from flask import request
def test():
    print(request.form.get("document_json"))

At the api is defined like this:

    post:
      operationId: app.test
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                document_json:
                  type: object
            encoding:
              document_json:
                contentType: application/json
      responses:
        200:
          description: returns

and I make this request to the server:

r = requests.post(
        "http://127.0.0.1:5001/test",
        data={"document_json":"illegal json"}
    )
    print(r.text)

Additional info:

Output of the commands:

  • python --version: Python 3.7.7

  • pip show connexion | grep "^Version\:" : Version: 2.7.0

thiagobell avatar May 20 '20 15:05 thiagobell