Как перехватить исключение OperationalError, возникающее в основном потоке django
Я использую базу данных Postgres 16.2 в моем проекте Django 5.0, настроенную следующим образом:
### settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASS',
'HOST': 'DB_HOST',
'PORT': '5432',
}
}
Работает хорошо, никаких проблем нет.
Однако, когда я имитирую отключение базы данных (обычно я останавливаю службу базы данных на своем компьютере), я получаю исключение, которое мне не удается поймать:
Исключение брошено в потоке django-main-thread
перед входом в представление.
Я пытался использовать промежуточное ПО, но это не помогает:
from django.db.utils import OperationalError
from django.utils.deprecation import MiddlewareMixin
from rest_framework import status
from rest_framework.response import Response
class OperationalErrorMiddleware(MiddlewareMixin):
def __init__(self, get_response):
super().__init__(get_response)
def __call__(self, request):
try:
return self.get_response(request)
except OperationalError:
return Response({'status': "DB_ERROR"}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
Я также пытался использовать обработчики Django handler500
и DRF (Django REST Framework) EXCEPTION_HANDLER
, но и эти обработчики не перехватывают исключение.
Это исключение приводит к пустому ответу для клиента (ERR_EMPTY_RESPONSE
в Chrome), что плохо.
Как я могу поймать это исключение, чтобы показать более "удобную" ошибку?
В трассировке есть self.check_migrations()
- это происходит еще до того, как ваш сервер запущен, чтобы правильно принимать соединения, когда Django проверяет, должен ли он показать вам сообщение "у вас N миграций, которые не были запущены".
На рабочем сервере, таком как uwsgi или gunicorn, этого не произойдет (потому что эти проверки выполняются только на сервере разработки runserver
), и поэтому я не вижу причин, чтобы вы пытались справиться с этой конкретной ошибкой.