Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
视图中不存在异常的Python Django异常中间件_Python_Django_Exception Handling - Fatal编程技术网

视图中不存在异常的Python 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

每当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.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):
    ....