视图中不存在异常的Python Django异常中间件
每当django应用程序中发现异常时,我都希望使用自定义中间件类来处理异常并发送电子邮件视图中不存在异常的Python Django异常中间件,python,django,exception-handling,Python,Django,Exception Handling,每当django应用程序中发现异常时,我都希望使用自定义中间件类来处理异常并发送电子邮件 import logging from django.core.mail import send_mail class ErrorMiddleware(object): logger = logging.getLogger(__name__) def process_exception(self, request, exception): self.logger.deb
import logging
from django.core.mail import send_mail
class ErrorMiddleware(object):
logger = logging.getLogger(__name__)
def process_exception(self, request, exception):
self.logger.debug("Middleware has caught an exception. exception={}".format(exception.message))
# send_mail("Your Subject", "This is a simple text email body.",
# "Yamil Asusta <hello@yamilasusta.com>", ["yamil@sendgrid.com"])
return None
并编写了以下测试用例来测试中间件是否处理我的异常
from django.test import TestCase
from mock import patch
from mock import Mock
class TestErrorMiddleware(TestCase):
def test_process_exception_catches_exceptions(self):
raise Exception
但是,当我通过manage.py运行测试时,我的日志中没有显示我的日志消息
我缺少什么?一旦web服务器启动,每个中间件都会初始化。但要实现这一点,您需要中间件中的\uuuu init\uuuu()
def __init__(self, get_response):
self.get_response = get_response
在初始化中间件之后,它需要有一个\uuuu call\uuu()方法,该方法在客户端的每个请求上都会被调用。正是这种方法负责将控制器传递给底层中间件,或在最后一层(即视图中间件)之后调用实际视图
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = self.get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
您需要从进程异常()返回一个HTTPResponse(),该异常将在上述代码中的响应变量中调用中间件的。,然后在退出时将其传递给其上方的中间件
由于中间件类中没有\uuuu init\uuuu()和\uuuu call\uuuuu(),因此中间件没有初始化,因此在中间件层来回传递时处理每个请求
参考:
虽然@cdx530的响应是正确的,但为Django pre-1.10设计的中间件有一个向后兼容性垫片,作为中间件类,它提供(几乎)与当代中间件方法相同的功能,imho在不同的中间件处理阶段之间提供了更好的结构和分离 只需从MiddlewareMixin派生中间件类:
from django.middleware.common import MiddlewareMixin
class ErrorMiddleware(MiddlewareMixin):
....
除非您已经重写了_uinit _;,否则您不需要做任何其他事情__在这种情况下,永远不会使用call_uuuu,这对于旧的行为很好,mixin类将自动在您的process_请求和process_响应/processs_异常之间调用get_请求
当前的Django文档在此处包括对该主题的讨论:
包括解释行为上的细微差异。您是否正确设置了日志处理程序?但是。。。您的测试本身只会引发一个异常。您没有在请求的上下文中运行它,那么中间件怎么可能捕获它呢?我希望它捕获所有异常,而不仅仅是视图中的请求中出现的异常。但是中间件不是魔术。它只能捕获在中间件实际运行的上下文中发生的错误;也就是说,在一个请求内。
from django.middleware.common import MiddlewareMixin
class ErrorMiddleware(MiddlewareMixin):
....