6

我正面临着 Flup 提出的可怕的“未处理异常”。可悲的是它是在网络服务器(lighttpd+flup)级别而不是在应用程序级别(Django)提出的。因此,不会就问题所在提出 500 封电子邮件。

我们整个团队都在努力清理代码库,以防有任何模棱两可的导入和类似的情况,只是为了消除由于模棱两可的导入而引发错误的机会。我们清理了代码中的许多内容。还是一样的例外。

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

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

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

我如何调试(至少)这种情况并解决问题?请帮帮我。该应用程序已关闭 3 天。

4

3 回答 3

9

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

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

然后使用经过修改的 Django 运行应用程序,您将看到 Flup 回溯的全部荣耀。

于 2009-02-09T15:26:13.747 回答
6

我遇到了类似的事情——我们让 Django 支持 NGINX,我们允许 Django 处理 500 次——这在 99.9% 的时间里都有效,但是当我们进行升级时,有时这些“未处理的异常”会漏掉。

Django 不会覆盖 Flup 的处理错误的钩子,所以我们需要自己做,让 Django 处理这些错误。

flup.server.BaseFCGIServer.error首先通过 Django覆盖错误。然后我们将告诉 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 级别的错误!

于 2010-11-07T22:58:55.470 回答
3

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

我首先尝试在您的应用程序文件中运行 PDB,或者至少在您调用 Flup 服务器 .run() 方法之前写入日志文件。这样您就可以将问题识别为 fastcgi 或 Flup 中的问题。请参阅mod_wsgi wiki 中名为Python 交互式调试器的部分。这可能会给你一些想法,让你知道如何用 lighttpd 和 Flup 做同样的事情。

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

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

尝试在 nginx+fastcgi 下运行你的应用程序,看看它是否有效,或者至少会给你更好的错误消息。

顺便说一句,flup 的作者讨厌 FCGI,甚至不再使用 flup ... 我建议切换到 nginx 或 apache+mod_wsgi。

于 2009-02-09T08:30:03.123 回答