Как я могу поймать все 500 и более ошибок в DRF и зарегистрировать их?

Я просмотрел многие ответы 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/месяц легко.

Andrew 15.12.2020 14:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
1 233
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не совсем знаком с 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).

Другие вопросы по теме