Improve validator error handling

This commit is contained in:
Cristi Vîjdea
2018-01-11 21:19:42 +01:00
parent c225f66fb7
commit 57d77cc48a
6 changed files with 23 additions and 15 deletions
+14 -7
View File
@@ -12,22 +12,22 @@ from .app_settings import swagger_settings
from .errors import SwaggerValidationError
def _validate_flex(spec, codec):
def _validate_flex(spec):
from flex.core import parse as validate_flex
from flex.exceptions import ValidationError
try:
validate_flex(spec)
except ValidationError as ex:
raise_from(SwaggerValidationError(str(ex), 'flex', spec, codec), ex)
raise_from(SwaggerValidationError(str(ex)), ex)
def _validate_swagger_spec_validator(spec, codec):
def _validate_swagger_spec_validator(spec):
from swagger_spec_validator.validator20 import validate_spec as validate_ssv
from swagger_spec_validator.common import SwaggerValidationError as SSVErr
try:
validate_ssv(spec)
except SSVErr as ex:
raise_from(SwaggerValidationError(str(ex), 'swagger_spec_validator', spec, codec), ex)
raise_from(SwaggerValidationError(str(ex)), ex)
#:
@@ -61,10 +61,17 @@ class _OpenAPICodec(object):
raise TypeError('Expected a `openapi.Swagger` instance')
spec = self.generate_swagger_object(document)
errors = {}
for validator in self.validators:
# validate a deepcopy of the spec to prevent the validator from messing with it
# for example, swagger_spec_validator adds an x-scope property to all references
VALIDATORS[validator](copy.deepcopy(spec), self)
try:
# validate a deepcopy of the spec to prevent the validator from messing with it
# for example, swagger_spec_validator adds an x-scope property to all references
VALIDATORS[validator](copy.deepcopy(spec))
except SwaggerValidationError as e:
errors[validator] = str(e)
if errors:
raise SwaggerValidationError("spec validation failed", errors, spec, self)
return force_bytes(self._dump_dict(spec))
def encode_error(self, err):
+2 -2
View File
@@ -3,9 +3,9 @@ class SwaggerError(Exception):
class SwaggerValidationError(SwaggerError):
def __init__(self, msg, validator_name, spec, source_codec, *args):
def __init__(self, msg, errors=None, spec=None, source_codec=None, *args):
super(SwaggerValidationError, self).__init__(msg, *args)
self.validator_name = validator_name
self.errors = errors
self.spec = spec
self.source_codec = source_codec
+1 -1
View File
@@ -13,7 +13,7 @@ class SwaggerExceptionMiddleware(object):
def process_exception(self, request, exception):
if isinstance(exception, SwaggerValidationError):
err = {'errors': {exception.validator_name: str(exception)}}
err = {'errors': exception.errors, 'message': str(exception)}
codec = exception.source_codec
if isinstance(codec, _OpenAPICodec):
err = codec.encode_error(err)
+1 -1
View File
@@ -9,7 +9,7 @@ from .codecs import VALIDATORS, OpenAPICodecJson, OpenAPICodecYaml
class _SpecRenderer(BaseRenderer):
"""Base class for text renderers. Handles encoding and validation."""
charset = None
validators = ['ssv', 'flex']
validators = []
codec_class = None
@classmethod
+3 -2
View File
@@ -12,8 +12,9 @@ from rest_framework.views import APIView
from .app_settings import swagger_settings
from .generators import OpenAPISchemaGenerator
from .renderers import OpenAPIRenderer, ReDocRenderer, SwaggerJSONRenderer, SwaggerUIRenderer, SwaggerYAMLRenderer, \
ReDocAlphaRenderer
from .renderers import (
OpenAPIRenderer, ReDocAlphaRenderer, ReDocRenderer, SwaggerJSONRenderer, SwaggerUIRenderer, SwaggerYAMLRenderer
)
SPEC_RENDERERS = (SwaggerYAMLRenderer, SwaggerJSONRenderer, OpenAPIRenderer)
UI_RENDERERS = {