Django. Как вернуть ошибку 500 без отправки почты администраторам
Я использую стандартную обработку ошибок в продакшене - если есть ошибки сервера, я получаю письма. Однако на некоторых API я хочу иметь ответ с HTTP кодом 500 или 502 как часть "валидного потока". (Это делается в образовательных целях)
Так что мой взгляд на это выглядит следующим образом:
from rest_framework.response import Response
from rest_framework import status
def give_me_error(request):
return Response("This is expected error", status=status.HTTP_500_INTERNAL_SERVER_ERROR)
И что я хочу - не получить по электронной почте именно этот ответ (потому что я хотел, чтобы их было 500)
Я также пробовал этот способ:
from django.http import JsonResponse
def give_me_error(request):
return JsonResponse({'error': 'expected error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Но он также генерирует почту.
Есть ли способ иметь представление, возвращающее ошибку 500, которое не будет вызывать отправку электронной почты? (без отключения функциональности электронной почты во всей системе)
По документации Django: https://docs.djangoproject.com/en/4.0/howto/error-reporting/
Когда значение DEBUG равно False, Django будет отправлять сообщения пользователям, указанным в настройке ADMINS, всякий раз, когда ваш код вызывает необработанное исключение и приводит к внутренней ошибке сервера (строго говоря, для любого ответа с кодом состояния HTTP 500 или более)
.
Посмотрим код и документацию
Похоже, что Django
использует класс ExceptionReporter
для отправки почты, поэтому мы должны изменить его:
class ExceptionReporterWithoutMail(ExceptionReporter):
def __init__(self, request, exc_type, exc_value, tb, is_email=False):
# set mail sending to False even it it was True to prevent sending messages
is_mail = False
# now run original ExceptionReporter's constructor with turned off mail
super().__init__(request, exc_type, exc_value, tb, is_email)
Теперь у нас есть дочерний класс, который не будет отправлять почту, и мы можем использовать его внутри нашего представления:
def give_me_error(request):
# set reporter class to ExceptionReporterWithoutMail instead of default one
request.exception_reporter_class = ExceptionReporterWithoutMail()
return JsonResponse({'error': 'expected error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
<
<