pyramid_swagger icon indicating copy to clipboard operation
pyramid_swagger copied to clipboard

pyramid_swagger is not returning an easily parsable exception message

Open tomelm opened this issue 9 years ago • 7 comments
trafficstars

I'm getting a RequestValidationError for a missing param but pyramid seems to be stringifying the error message:

ipdb> e
<RequestValidationError at 0x7f39c1cbeb88 400 Bad Request>
ipdb> e.__class__
<class 'pyramid_swagger.exceptions.RequestValidationError'>
ipdb> e.message
"phone is a required parameter.\n\nFailed validating 'required' in schema:\n    {'in': 'query',\n     'maxLength': 50,\n     'name': 'phone',\n     'required': True,\n     'type': 'string'}\n\nOn instance:\n    None"

I could do some kind of nasty string parsing to make this usable but that's not ideal. There doesn't appear to be any way to pull a well-formatted message

ipdb> e.args
("phone is a required parameter.\n\nFailed validating 'required' in schema:\n    {'in': 'query',\n     'maxLength': 50,\n     'name': 'phone',\n     'required': True,\n     'type': 'string'}\n\nOn instance:\n    None",)
ipdb> e.json
*** simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
ipdb> e.json_body
*** simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
ipdb> e.body
b''

tomelm avatar Aug 18 '16 16:08 tomelm

The main reason this is an issue is because it makes it impossible for me to programmatically determine which field failed validation. In the case where we're building APIs, if I can't tell which field failed I don't have a way to structure the failure message appropriately without simply passing back the entire message body (which is not valid ideal in the case where we're going from internal => external)

tomelm avatar Aug 18 '16 17:08 tomelm

@tomelm did you find any solution ? I experimenting same issue when testing around parameter validation and a suitable json output structure

gdchamal avatar Nov 25 '16 17:11 gdchamal

Bumping this, I will probably also run into this problem soon.

ergo avatar Mar 14 '18 22:03 ergo

@gdchamal @tomelm, I've found that when you grab RequestValidationError it has child property that will return ValidationError from bravado that you can inspect for errors.

ergo avatar Mar 14 '18 23:03 ergo

Here is an example (maybe a bit naive) implementation that shows how to return a json response with error information:

def exc_view(exc, request):
    error_info = exc.child
    for_json = {
        'message': getattr(error_info, 'message', u'{}'.format(error_info)),
        'validator': getattr(error_info, 'validator', None),
        'relative_schema_path': list(
            getattr(error_info, 'relative_schema_path', []))[:-1],
        'schema': getattr(error_info, 'schema', None),
        'relative_path': list(getattr(error_info, 'relative_path', [])),
        'instance': getattr(error_info, 'instance', None)
    }

    return for_json

config.add_exception_view(
    context='pyramid_swagger.exceptions.RequestValidationError',
    view=exc_view, renderer='json')

Example response:

{
  "message": "8 is not of type 'string'",
  "validator": "type",
  "relative_schema_path": [
    "properties",
    "city"
  ],
  "schema": {
    "type": "string",
    "example": "doggie"
  },
  "relative_path": [
    "city"
  ],
  "instance": 8
}

ergo avatar Mar 15 '18 00:03 ergo

@striglia I think the issue can be closed, I could add the example to documentation.

ergo avatar Mar 15 '18 00:03 ergo

thank you @ergo , I'll test your solution ASAP

gdchamal avatar Mar 15 '18 11:03 gdchamal