Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/objecttypes/conf/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"DEFAULT_VERSION": "v2", # NOT to be confused with API_VERSION - it's the major version part
"ALLOWED_VERSIONS": ("v2",),
"VERSION_PARAM": "version",
"EXCEPTION_HANDLER": "objecttypes.utils.views.exception_handler",
# test
"TEST_REQUEST_DEFAULT_FORMAT": "json",
}
Expand Down
47 changes: 47 additions & 0 deletions src/objecttypes/utils/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
from django import http
from django.template import TemplateDoesNotExist, loader
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import requires_csrf_token
from django.views.defaults import ERROR_500_TEMPLATE_NAME

import structlog
from open_api_framework.conf.utils import config
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import exception_handler as drf_exception_handler

logger = structlog.stdlib.get_logger(__name__)

DEFAULT_CODE = "invalid"
DEFAULT_DETAIL = _("Invalid input.")


@requires_csrf_token
def server_error(request, template_name=ERROR_500_TEMPLATE_NAME):
Expand All @@ -23,3 +35,38 @@ def server_error(request, template_name=ERROR_500_TEMPLATE_NAME):
)
context = {"request": request}
return http.HttpResponseServerError(template.render(context))


def exception_handler(exc, context):
"""
Transform 5xx errors into DSO-compliant shape.
"""
response = drf_exception_handler(exc, context)
if not response:
if config("DEBUG", default=False):
return None

data = {
"code": "error",
"title": "Internal Server Error",
"status": status.HTTP_500_INTERNAL_SERVER_ERROR,
"detail": _("A server error has occurred."),
}
event = "api.uncaught_exception"

response = Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR, data=data)
logger.exception(event, exc_info=exc)

return response

# exception logger event
logger.exception(
"api.handled_exception",
title=getattr(exc, "default_detail", DEFAULT_DETAIL).strip("'"),
code=getattr(exc, "default_code", DEFAULT_CODE),
status=getattr(response, "status_code", status.HTTP_400_BAD_REQUEST),
data=getattr(response, "data", {}),
exc_info=False,
)

return response
Loading