Django 2.0 自定义中间件 process_exception 挂钩未触发
Django 2.0 custom middleware process_exception hook not firing
我的自定义中间件 class 似乎在响应周期中跳过了 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 调试页面,表明已经处理了异常,但我的印象是将我的中间件作为列表中的最后一个意味着它应该是第一个访问响应周期?
EDIT 所以在进一步播放时,看起来这与 DjangoDebugToolbar 有某种关系,当我禁用它并删除中间件时,我的中间件工作正常。我对此感到困惑,因为我的中间件应该先触发。
编辑 2 具体来说,它似乎是分析面板?评论它解决了这个问题......多么奇怪
所以我最终发现 https://github.com/jazzband/django-debug-toolbar/issues/497 将其列为 Django 调试工具栏中 Profiling 面板的错误。非常令人沮丧,因为它以一种极其不明显的方式中断。
修复是:不要使用分析面板或将 Django 调试工具栏放在中间件列表的最后,并接受 DDT 不会监视任何中间件 类
我的自定义中间件 class 似乎在响应周期中跳过了 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 调试页面,表明已经处理了异常,但我的印象是将我的中间件作为列表中的最后一个意味着它应该是第一个访问响应周期?
EDIT 所以在进一步播放时,看起来这与 DjangoDebugToolbar 有某种关系,当我禁用它并删除中间件时,我的中间件工作正常。我对此感到困惑,因为我的中间件应该先触发。
编辑 2 具体来说,它似乎是分析面板?评论它解决了这个问题......多么奇怪
所以我最终发现 https://github.com/jazzband/django-debug-toolbar/issues/497 将其列为 Django 调试工具栏中 Profiling 面板的错误。非常令人沮丧,因为它以一种极其不明显的方式中断。
修复是:不要使用分析面板或将 Django 调试工具栏放在中间件列表的最后,并接受 DDT 不会监视任何中间件 类