21ea527623
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
103 lines
4.1 KiB
Python
103 lines
4.1 KiB
Python
"""Error Response schema, from https://github.com/axnsan12/drf-yasg/issues/224"""
|
|
from drf_yasg import openapi
|
|
from drf_yasg.inspectors.view import SwaggerAutoSchema
|
|
from drf_yasg.utils import force_real_str, is_list_view
|
|
from rest_framework import exceptions, status
|
|
from rest_framework.settings import api_settings
|
|
|
|
|
|
class ErrorResponseAutoSchema(SwaggerAutoSchema):
|
|
"""Inspector which includes an error schema"""
|
|
|
|
def get_generic_error_schema(self):
|
|
"""Get a generic error schema"""
|
|
return openapi.Schema(
|
|
"Generic API Error",
|
|
type=openapi.TYPE_OBJECT,
|
|
properties={
|
|
"detail": openapi.Schema(
|
|
type=openapi.TYPE_STRING, description="Error details"
|
|
),
|
|
"code": openapi.Schema(
|
|
type=openapi.TYPE_STRING, description="Error code"
|
|
),
|
|
},
|
|
required=["detail"],
|
|
)
|
|
|
|
def get_validation_error_schema(self):
|
|
"""Get a generic validation error schema"""
|
|
return openapi.Schema(
|
|
"Validation Error",
|
|
type=openapi.TYPE_OBJECT,
|
|
properties={
|
|
api_settings.NON_FIELD_ERRORS_KEY: openapi.Schema(
|
|
description="List of validation errors not related to any field",
|
|
type=openapi.TYPE_ARRAY,
|
|
items=openapi.Schema(type=openapi.TYPE_STRING),
|
|
),
|
|
},
|
|
additional_properties=openapi.Schema(
|
|
description=(
|
|
"A list of error messages for each "
|
|
"field that triggered a validation error"
|
|
),
|
|
type=openapi.TYPE_ARRAY,
|
|
items=openapi.Schema(type=openapi.TYPE_STRING),
|
|
),
|
|
)
|
|
|
|
def get_response_serializers(self):
|
|
responses = super().get_response_serializers()
|
|
definitions = self.components.with_scope(
|
|
openapi.SCHEMA_DEFINITIONS
|
|
) # type: openapi.ReferenceResolver
|
|
|
|
definitions.setdefault("GenericError", self.get_generic_error_schema)
|
|
definitions.setdefault("ValidationError", self.get_validation_error_schema)
|
|
definitions.setdefault("APIException", self.get_generic_error_schema)
|
|
|
|
if self.get_request_serializer() or self.get_query_serializer():
|
|
responses.setdefault(
|
|
exceptions.ValidationError.status_code,
|
|
openapi.Response(
|
|
description=force_real_str(
|
|
exceptions.ValidationError.default_detail
|
|
),
|
|
schema=openapi.SchemaRef(definitions, "ValidationError"),
|
|
),
|
|
)
|
|
|
|
security = self.get_security()
|
|
if security is None or len(security) > 0:
|
|
# Note: 401 error codes are coerced into 403 see
|
|
# rest_framework/views.py:433:handle_exception
|
|
# This is b/c the API uses token auth which doesn't have WWW-Authenticate header
|
|
responses.setdefault(
|
|
status.HTTP_403_FORBIDDEN,
|
|
openapi.Response(
|
|
description="Authentication credentials were invalid, absent or insufficient.",
|
|
schema=openapi.SchemaRef(definitions, "GenericError"),
|
|
),
|
|
)
|
|
if not is_list_view(self.path, self.method, self.view):
|
|
responses.setdefault(
|
|
exceptions.PermissionDenied.status_code,
|
|
openapi.Response(
|
|
description="Permission denied.",
|
|
schema=openapi.SchemaRef(definitions, "APIException"),
|
|
),
|
|
)
|
|
responses.setdefault(
|
|
exceptions.NotFound.status_code,
|
|
openapi.Response(
|
|
description=(
|
|
"Object does not exist or caller "
|
|
"has insufficient permissions to access it."
|
|
),
|
|
schema=openapi.SchemaRef(definitions, "APIException"),
|
|
),
|
|
)
|
|
|
|
return responses
|