Я просмотрел многие ответы SO относительно реализации этого, но я не могу найти что-то, что не устарело, или что-то, что действительно работает для моего варианта использования.
По сути, у меня есть несколько методов API, которые возвращают свои собственные коды состояния. Однако, если по какой-либо причине возникает ошибка сервера 500 или что-либо выше 500, что указывает на то, что произошло что-то странное (например, скажем, время ожидания соединения с базой данных), я хочу, чтобы это было зарегистрировано в файле или отправлено по электронной почте администратору.
Я пытался использовать собственный обработчик исключений, но не все 500 ошибок являются исключениями.
Поэтому я прибегнул к написанию собственного промежуточного программного обеспечения, которое выглядело примерно так:
class CustomApiLoggingMiddleware(MiddlewareMixin):
def process_response(self, request, response):
if response.path.startswith('/api/'):
...do stuff here
Проблема, однако, в том, что, похоже, нет status_code
. Честно говоря, я действительно не знаю, какой ответ я на самом деле получаю. Есть ответ 500, возвращаемый моим API намеренно в результате метода API, и есть ответ 500, сгенерированный Django в бэкэнде, если какое-то условие не выполняется (скажем, они отправили запрос без надлежащего заголовка)
Я попытался намеренно сгенерировать ответ/ошибку 500, вернув Response(status=status.HTTP_500)
в какой-то базовый /500
маршрут. Несмотря на то, что это запускает промежуточное ПО, я не могу использовать status_code
, чтобы проверить, действительно ли ответ равен 500 или нет.
Я даже не уверен, что делаю это правильно, но, надеюсь, вы понимаете мое намерение. В основном я хотел бы перехватить все необработанные исключения, которые могут произойти в результате моих вызовов API, и зарегистрировать их или отправить администратору. Большинство вызовов, которые возвращают примерно 40X или что-то еще, обрабатываются так, как я уже хочу.
Я бы посмотрел на sentry.io в этом случае вы получите лучшие журналы ошибок, и он довольно легко интегрируется со всем. Не шиллинг, но пользуюсь уже лет 5 и больше и жить без него не буду. Его используют все наши проекты dajngo, веб-приложения и даже некоторые инструменты командной строки. Стоит 30/месяц легко.
Я не совсем знаком с MiddlewareMixin
, но простая реализация с вызываемым классом, как описано в документации, похоже, работает:
class ResponseStatusMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
print(f"Response has status {response.status_code}")
return response
Это отлично работает, когда представление работает return HttpResponse(status=500)
со стандартным Django HttpResponse
. Однако, когда представление вызывает исключение, промежуточное ПО может быть обойдено из-за обработки исключений Django Rest Framework. Если get_response
вызывает исключение, вы можете обработать его, реализовав хук process_exception
в промежуточном программном обеспечении:
class ResponseStatusMiddleware:
...
def process_exception(self, request, exception):
...log your exception...
Вы также можете преобразовать неперехваченные исключения в объекты ответа с помощью специального обработчика или, если возможно, преобразовать их в DRF APIException
, который обрабатывается автоматически.
Кроме того, status.HTTP_500
, вероятно, должен быть status.HTTP_500_INTERNAL_SERVER_ERROR
(см. документацию DRF).