openapi-core
openapi-core copied to clipboard
Errors are less verbose than they need to be
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 https://github.com/OAI/OpenAPI-Specification/issues/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?
Yes that's something that can be changed.
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.