Skip to content

Errors are less verbose than they need to be #241

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
stephenfin opened this issue Apr 15, 2020 · 2 comments
Open

Errors are less verbose than they need to be #241

stephenfin opened this issue Apr 15, 2020 · 2 comments
Labels
area/unmarshalling Indicates an issue on unmarshalling area. kind/enhancement

Comments

@stephenfin
Copy link
Contributor

stephenfin commented Apr 15, 2020

Thanks for the excellent library. I have a request. I'm currently getting error messages like the following for an invalid schema:

Traceback (most recent call last):
  ...
  File ".../openapi_core/unmarshalling/schemas/unmarshallers.py", line 61, in validate
    value, self.schema.type, schema_errors=errors)
openapi_core.unmarshalling.schemas.exceptions.InvalidSchemaValue: Value [{'id': 1, ...}] not valid for schema of type SchemaType.ARRAY: (<ValidationError: 'None for not nullable'>,)

This isn't very helpful, and it took me a while to figure out what was happening (I was running into OAI/OpenAPI-Specification#1368). I managed it by hacking on openapi-core in my venv and adding the following:

diff --git openapi_core/unmarshalling/schemas/unmarshallers.py openapi_core/unmarshalling/schemas/unmarshallers.py
index b60f9c3..9b4ddea 100644
--- openapi_core/unmarshalling/schemas/unmarshallers.py
+++ openapi_core/unmarshalling/schemas/unmarshallers.py
@@ -54,6 +54,7 @@ class PrimitiveTypeUnmarshaller(object):
             raise InvalidSchemaValue(value, self.schema.type)
 
     def validate(self, value):
+        self.validator.validate(value)
         errors_iter = self.validator.iter_errors(value)
         errors = tuple(errors_iter)
         if errors:

which gave me a far more helpful:

Traceback (most recent call last):
  ...
  File ".../openapi_core/unmarshalling/schemas/unmarshallers.py", line 57, in validate
    self.validator.validate(value)
  File ".../jsonschema/validators.py", line 353, in validate
    raise error
jsonschema.exceptions.ValidationError: None for not nullable

Failed validating 'nullable' in schema['items']['properties']['delegate']['allOf'][0]:
    {'nullable': False,
     'properties': {'email': {'format': 'email',
                              'minLength': 1,
                              'readOnly': True,
                              'title': 'Email address',
                              'type': 'string'},
                    'first_name': {'maxLength': 30,
                                   'readOnly': True,
                                   'title': 'First name',
                                   'type': 'string'},
                    'id': {'readOnly': True,
                           'title': 'ID',
                           'type': 'integer'},
                    'last_name': {'maxLength': 150,
                                  'readOnly': True,
                                  'title': 'Last name',
                                  'type': 'string'},
                    'url': {'format': 'uri',
                            'readOnly': True,
                            'title': 'URL',
                            'type': 'string'},
                    'username': {'maxLength': 150,
                                 'minLength': 1,
                                 'readOnly': True,
                                 'title': 'Username',
                                 'type': 'string'}},
     'type': 'object'}

On instance[0]['delegate']:
    None

I understand that you probably don't want to raise an exception immediately since you'd only see the first error, but would it be possible to opt-in to this behavior, or at least surface up the more verbose error message, assuming jsonschema provides a way to access this?

@p1c2u
Copy link
Collaborator

p1c2u commented Apr 23, 2020

Yes that's something that can be changed.

@p1c2u p1c2u added area/unmarshalling Indicates an issue on unmarshalling area. kind/enhancement labels Apr 23, 2020
@osynge
Copy link

osynge commented Nov 1, 2021

I find this code now works (note it uses structlog to log messages):

def _openapi_log_errors(message, function_name, validation_errors):
    """Log all validation errors in a way that can be addressed."""
    for error_validation in validation_errors:
        if len(error_validation.schema_errors) == 0:
            # Catch when error does not have errors in schema_errors property.
            # This should never happen.
            logger.critical(
                event=message,
                value=error_validation.value
            )
        for schema_error in error_validation.schema_errors:
            schema_absolute_path = ".".join(schema_error.absolute_path)
            if len(schema_absolute_path) == 0:
                schema_absolute_path = '.'
            logger.error(
                event=message,
                function=function_name,
                schema_error=schema_error.message,
                schema_cause=schema_error.cause,
                schema_validator=schema_error.validator,
                schema_path=schema_absolute_path,
            )

And here we get the result from our validation:

        if len(request_validate_result.errors) > 0:
            _openapi_log_errors(
                message="openapi_request_validator failed",
                function_name=func.__name__,
                validation_errors=request_validate_result.errors
            )

So after some pokeng around I feel this bug is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/unmarshalling Indicates an issue on unmarshalling area. kind/enhancement
Projects
None yet
Development

No branches or pull requests

3 participants