Пользовательский хук process_exception промежуточного программного обеспечения Django 2.0 не срабатывает

Мой пользовательский класс промежуточного программного обеспечения, похоже, пропускает этап process_exception во время цикла ответа.

from django.utils.deprecation import MiddlewareMixin

class MyMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print("Request!")

    def process_response(self, request, response):
        print("Response!")
        return response

    def process_exception(self, request, exception):
        print("Exception!")

Промежуточное ПО настроено....

DJANGO_MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
]

LOCAL_MIDDLEWARE = [
    'path.to.MyMiddleware',
]

MIDDLEWARE = DJANGO_MIDDLEWARE + LOCAL_MIDDLEWARE

и похоронен в моем коде представления:

def some_view(request):
    ...
    raise Exception("foo")

Однако, когда я нажимаю URL-адрес, я получаю это в журнале консоли:

Request!
Internal Server Error: /my/url/
Traceback (most recent call last):
  ... long traceback ...
  File "/path/to/my/views.py", line 184, in some_view
    raise Exception("foo")
Exception: foo
ERROR django.request 2019-01-24 11:50:48,270 [exception.py handle_uncaught_exception 118] Internal Server Error: /my/url/
Traceback (most recent call last):
  ... long traceback ...
  File "/path/to/my/views.py", line 184, in some_view
    raise Exception("foo")
Exception: foo
Response!

Как видите, process_exception вообще не вызывается, process_request и process_response оба. И по какой-то причине трассировка исключения отображается дважды, прежде чем process_response моего промежуточного программного обеспечения даже не сработает. Ответ, который передается process_response для моего промежуточного программного обеспечения, представляет собой стандартную страницу отладки Django 500, предполагающую, что исключение уже было обработано, но у меня сложилось впечатление, что наличие моего промежуточного программного обеспечения в качестве последнего в списке означает, что оно должно быть первым. доступ для цикла ответа?

РЕДАКТИРОВАТЬ Итак, при дальнейшем воспроизведении похоже, что это как-то связано с DjangoDebugToolbar, когда я отключаю это и удаляю промежуточное ПО, мое промежуточное ПО работает нормально. Я озадачен этим, потому что мое промежуточное ПО должно запускаться первым.

EDIT 2 В частности, это панель профилирования? комментирование решает проблему... как странно


person ptr    schedule 24.01.2019    source источник
comment
Ваш код выглядит правильно для меня. Вы уверены, Исключение! нет нигде в выводе? (Вы пропустили его, поэтому трудно быть уверенным.) В качестве дополнительной проверки попробуйте вернуть ответ от вашего process_exception().   -  person Kevin Christopher Henry    schedule 24.01.2019
comment
Я проверил вывод - нет следов оператора печати. Я добавил точку останова pdb, и она тоже не сработала, поэтому метод полностью пропускается. Я продолжу копать, чтобы увидеть, есть ли какая-то архаичная обработка ошибок дальше в коде, который все портит.   -  person ptr    schedule 24.01.2019
comment
Обновил вопрос - похоже, причиной является панель инструментов отладки. пока нет решения   -  person ptr    schedule 24.01.2019


Ответы (1)


В конце концов я нашел https://github.com/jazzband/django-debug-toolbar/issues/497, в котором это указано как ошибка с панелью профилирования на панели инструментов отладки Django. Довольно неприятно, так как он ломается крайне неочевидным образом.

Исправления: не используйте панель профилирования или ставьте панель инструментов отладки Django последней в списке промежуточного программного обеспечения и соглашайтесь с тем, что DDT не будет отслеживать ни один из ваших классов промежуточного программного обеспечения.

person ptr    schedule 24.01.2019