Вручную вызвать отчет об ошибке электронной почты Django

отчеты об ошибках Django обрабатывает необработанные исключения, отправляя электронное письмо, и (необязательно) показывает пользователю хорошую страницу ошибок 500.

Это работает очень хорошо, но в некоторых случаях я хотел бы позволить пользователям продолжать свой бизнес бесперебойно, но все еще есть Django отправить мне сообщение об ошибке электронной почты об исключении.

Итак, в основном: могу ли я вручную отправить отчет об ошибке электронной почты, даже если я поймаю исключение?

конечно, я хотел бы чтобы избежать создания сообщения об ошибке вручную.

4 ответов


вы можете использовать следующий код, чтобы отправить вручную письмо о request исключение e:

import sys
import traceback
from django.core import mail
from django.views.debug import ExceptionReporter

def send_manually_exception_email(request, e):
    exc_info = sys.exc_info()
    reporter = ExceptionReporter(request, is_email=True, *exc_info)
    subject = e.message.replace('\n', '\n').replace('\r', '\r')[:989]
    message = "%s\n\n%s" % (
        '\n'.join(traceback.format_exception(*exc_info)),
        reporter.filter.get_request_repr(request)
    )
    mail.mail_admins(
        subject, message, fail_silently=True,
        html_message=reporter.get_traceback_html()
    )

вы можете проверить его в таком виде:

def test_view(request):
    try:
        raise Exception
    except Exception as e:
        send_manually_exception_email(request, e)

просто настройте простой обработчик журнала в своих настройках.

LOGGING = {
    'version': 1, 
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'app': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

и тогда, на ваш взгляд, вы можете сделать что угодно

 import logging
 logger = logging.getLogger('app')

 def some_view(request):
     try:
         # something
         if something_wnet_wrong:
             logger.error('Something went wrong!')
         return some_http_response
     except:
         #something else
         logger.error(sys.exc_info(), request)        
         return some_other_response

Если вы хотите подробный отчет об ошибках, вы можете попробовать как то так.

Вам также нужно позаботиться о конфиденциальную информацию.


Да, вы можете вручную отправить отчет об ошибке электронной почты, даже если вы поймаете исключение.

есть несколько способов, вы можете пойти об этом.

  1. вы можете использовать существующую конфигурацию регистратора по умолчанию (и связанную с ней конфигурацию обработчика, документированную здесь) для Django.запрос, который отправляет все сообщения об ошибках обработчику mail_admins, который отправляет все, что зарегистрировано с журналом.ошибка от django.запрос при отладке false как email с использованием AdminEmailHandler, чья существующая точка вызова находится в handle_uncaught_exception.
  2. вы можете добавить дополнительную конфигурацию регистратора, которая использует тот же обработчик, чтобы поймать ваше исключение раньше, чем django.журнал запросов и вызовов.ошибка ранее.
  3. вы можете подкласс django.запрос, в частности handle_uncaught_exception.
  4. вы можете использовать настраиваемое промежуточное ПО (например, StandardExceptionMiddleware) или ExceptionMiddleware
  5. вы можете вручную вызвать содержимое emit в AdminEmailHandler или по почте.mail_admins напрямую.

из этих вариантов Вариант 4, по-видимому, наиболее часто выполняется.

на основе дополнительной информации в вашем комментарии ниже приведен пример кода 2.

сначала код, который будет добавлен в view

from django.http import HttpResponse
import logging
logger = logging.getLogger(__name__)

def my_view(request):

    try:
        result = do_something()
        return HttpResponse('<h1>Page was found' + result + '</h1>')
    except Exception: 
         # Can have whatever status_code and title you like, but I was just matching the existing call.
         logger.error('Internal Server Error: %s', request.path,
            exc_info=sys.exc_info(),
            extra={
            'status_code': 500,
            'request': request
            }
         )
         return HttpResponse('<h1>Page was found, and exception was mailed to admins.</h1>')

Это на основании Django документация для просмотра записи и и введение в ведение журнала Django, но не был протестирован.

затем дополнительная конфигурация регистратора добавляется к записи регистраторов (согласно здесь)

'nameofdjangoapplicationgoeshere': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },

Я в основном использую этот шаблон со стандартной отчетностью об ошибках.

import logging    
logger = logging.getLogger('django.request')

#code block in view
try:
    #code that can raise exception
except:
    logger.exception('Information')
#continue as nothing happend

он вызовет встроенный отчет об ошибках и лесоруб.исключение поймает кадр стека. https://docs.djangoproject.com/en/1.8/topics/logging/#making-logging-calls

edit:

Я заметил, что в письме отсутствует некоторая информация, и для получения точной обратной связи можно использовать встроенное следующее:

logger.exception('Internal Server Error: %s', request.path,
                 extra={'status_code': 500, 'request': request})

Подробнее найдено здесь: как Отправить журнал исключений django вручную?