Flup中未处理的异常

时间:2009-02-09 06:19:05

标签: django error-handling middleware fastcgi flup

我正面对Flup提出的可怕的“未处理的异常”。可悲的部分是它在webserver(lighttpd + flup)级别而不是在应用程序级别(Django)。所以没有提出关于问题所在的500封电子邮件。

我们整个团队努力清理代码库,包括任何恶劣的进口和某种类型的东西,只是为了消除因进口模糊而引发错误的可能性。我们在代码中清理了很多东西。仍然是同样的例外。

坦率地说,我对Flup的错误处理感到非常沮丧。它没有告诉你任何事情。最糟糕的是,它向用户显示了相同的“未处理的例外”。我如何通过这个?

我检查了lighttpd日志。我只看到“接口错误/连接已经关闭”。它只发生在我的应用程序在FCGI模式下运行时。所以问题在于flup实际上是如何处理我的代码(应用程序)的。我如何通过这个?

我检查了flup的替代方案,但是Django明确地依赖于flup(这是一个限制,并且困惑了我)(参考:django_src / django / core / servers / fastcgi.py line:100/131)

如何调试(至少)此方案并解决问题?请帮帮我。申请已经停止了3天。

3 个答案:

答案 0 :(得分:9)

这表明Django开始处理请求之前的错误,就像设置模块中的语法错误一样。调试此类问题的最快方法是打开FastCGI调试。这是django/core/servers/fastcgi.py中的第128行:

wsgi_opts['debug'] = False # Turn off flup tracebacks

然后用这样修改过的Django运行应用程序,你会看到整个荣耀中的Flup追溯。

答案 1 :(得分:6)

我遇到了类似的东西 - 我们让Django落后于NGINX,我们允许Django处理500s - 这有99.9%的时间可以工作,但是当我们进行升级时,有时这些“未处理的异常”会漏掉。 / p>

Django没有覆盖flup的钩子来处理错误,所以我们需要自己做,让Django处理这些错误。

首先通过Django覆盖flup.server.BaseFCGIServer.error错误。然后我们将告诉Django使用我们修改过的BaseFCGIServer来查看这些错误。

由于Python非常棒,我们会欺骗并在一个地方整理整个事物django.core.servers.fastcgi.py。我们走了:

# django.core.servers.fastcgi.py

def runfastcgi(argset=[], **kwargs):
    # ...

    # Paste his hack right after the `module` try/catch.

    # Override BaseFCGIServer.error to use Django error handling.
    # http://trac.saddi.com/flup/browser/flup/server/fcgi_base.py#L1210
    def patch_error(self, req):
        import sys
        from django.conf import settings
        from django.core import urlresolvers
        from django.core.handlers.wsgi import WSGIRequest

        urlconf = settings.ROOT_URLCONF
        urlresolvers.set_urlconf(urlconf)
        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)

        # No access to 'environ' so rebuild WSGIRequest.
        # http://trac.saddi.com/flup/browser/flup/server/fcgi_base.py#L1077
        environ = req.params
        environ.update(self.environ)
        environ['wsgi.version'] = (1,0)
        environ['wsgi.input'] = req.stdin
        self._sanitizeEnv(environ)        
        wsgireq = WSGIRequest(environ)

        # http://code.djangoproject.com/browser/django/trunk/django/core/handlers/base.py#L177    
        response = self.application.handle_uncaught_exception(wsgireq, resolver, sys.exc_info())

        # TODO: NGINX figures this out, but other servers might not.
        # http://trac.saddi.com/flup/browser/flup/server/fcgi_base.py#L1104
        req.stdout.write('Status: 500\r\n')
        req.stdout.write('Content-Type: text/html\r\n\r\n' + response.content)    

    WSGIServer.error = patch_error

现在您可以享受Django堆栈跟踪,即使是针对flup级错误!

答案 2 :(得分:3)

我不使用lighttpd或flup,所以这不是答案,而是提示。

我首先尝试在您的app文件中运行PDB,或者至少在调用flup服务器.run()方法之前写入日志文件。这样你就可以将问题识别为fastcgi或flup。请参阅mod_wsgi wiki中名为Python Interactive Debugger的部分。这可能会给你关于如何用lighttpd和flup做同样事情的想法。

然后,如果问题是flup,你将在pdb中捕获异常,并可以从那里进行调试。

如果问题是lighttpd,那么您的配置文件中可能存在某种问题,或者可能是lighttpd的构建方式存在问题。也许lighttp和fastcgi模块之间存在系统库不匹配的问题?

尝试在nginx + fastcgi下运行您的应用,看看它是否有效或至少为您提供更好的错误消息。

Btw,flup hates FCGI and doesn't even use flup anymore的作者...我建议切换到nginx或apache + mod_wsgi。