Перехват ошибки Django 500 для ведения журнала без создания/обслуживания пользовательского 500.html

#python #django #http-status-code-500

Вопрос:

Чтобы регистрировать ошибки «какой-то зависимости, где-то глубоко», которые вызывают ошибку сервера 500 , без следов стека в журнале консоли в рабочих экземплярах из DEBUG=False -за этого я реализовал стандартный пользовательский обработчик 500, который рекомендуется для большого количества вопросов Stackoverflow о печати трассировки стека для ошибки 500:

 import sys
import traceback

def server_error_500_handler(request):
    type, value, tb = sys.exc_info()
    print('n----intercepted 500 error stack trace----')
    print(value)
    print(type)
    print(traceback.format_exception(type, value, tb))
    print('----n')
 

Тем не менее, все это также говорит о том , чтобы закончить render(request, '500.html') , в то время как я не хочу обслуживать пользовательскую страницу 500, но хочу, чтобы код «вернулся» (если есть такая вещь), чтобы просто обслуживать то, что уже делает сам Django. Есть ли какой-то способ заставить его это сделать? Или есть ли какой-то способ прослушивать событие 500, не перехватывая кодовый путь возврата 500 ошибок?

Ответ №1:

Вместо того, чтобы создавать собственный обработчик 500, создайте собственное промежуточное программное обеспечение и реализуйте process_exception в нем метод:

 import traceback


class Log500ErrorsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response
    
    def process_exception(self, request, exception):
        print('n----intercepted 500 error stack trace----')
        print(exception)
        print(type(exception))
        tb = exception.__traceback__
        print(traceback.format_exception(type(exception), exception, tb))
        print('----n')
        return None # Let other middlewares do further processing
 

Затем добавить его в MIDDLEWARE настройки, все, как в самом конце, поскольку middlewares выполняются снизу вверх порядке в ходе ликвидации/исключения фазы, так что, если вы положите его в прошлом он всегда вам работать (некоторые промежуточное программное обеспечение может решить, короткого замыкания и возвращает ответ, в противном случае, то есть ничего после нее может предотвратить его запуск).

 MIDDLEWARE = [
    ...
    'path.to.Log500ErrorsMiddleware',
]
 

Комментарии:

1. Имеет ли значение, где в списке промежуточного программного обеспечения будет размещено это? (например, есть ли какое-либо конкретное промежуточное программное обеспечение Django, за которым оно должно следовать?)

2. @Mike’Pomax’Camermans поставил его последним , как я показываю в примере (обратите внимание на отсутствие трейлинга ... ), так как промежуточные программы запускаются снизу вверх во время фазы ответа / исключения, поэтому, если вы поставите его последним, он всегда будет запущен (некоторые промежуточные программы могут решить замкнуть и вернуть ответ в противном случае).