6

Flup によって発生した恐ろしい「ハンドルされていない例外」に直面しています。悲しい部分は、アプリケーション レベル (Django) ではなく、Web サーバー (lighttpd+flup) レベルで発生したことです。そのため、問題がどこにあるかについて 500 通の電子メールが送信されることはありません。

私たちのチーム全体は、あいまいなインポートやそのような人がいる場合に備えて、あいまいなインポートによるエラーが発生する可能性を排除するために、コードベースをクリーンアップするのに苦労しました. そして、コード内の多くのことをクリーンアップしました。それでも同じ例外です。

率直に言って、私は Flup のエラー処理に本当にイライラしています。それはあなたに何も教えてくれません。最悪の場合、同じ「未処理の例外」がユーザーに表示されます。どうすればこれをパスできますか?

lighttpd ログを確認しました。「インターフェイス エラー/接続が既に閉じられています」と表示されるだけです。アプリケーションが FCGI モードで実行されている場合にのみ発生します。したがって、問題は flup が実際に私のコード (アプリケーション) をどのように扱っているかということです。どうすればこれをパスできますか?

flup の代替案を調べたのですが、Django は明示的に flup に依存しています (これはもう 1 つの制限であり、私を困惑させました) (参照:django_src/django/core/servers/fastcgi.py 行: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

NGINX の背後に Django があり、Django が 500 を処理できるようにしています。これは 99.9% の確率で機能しますが、アップグレードを行っているときに、これらの「未処理の例外」がすり抜けることがあります。

Django は、エラーを処理するために flup のフックをオーバーライドしません。そのため、自分でそれを行い、Django にこれらのエラーを処理させる必要があります。

最初flup.server.BaseFCGIServer.errorに Django を介してエラーをオーバーライドします。BaseFCGIServer次に、修正したものを使用してこれらのエラーを確認するようにDjango に指示します。

Python は素晴らしいので、全体を 1 か所でチートしてモンキーパッチします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

flup レベルのエラーでも Django のスタック トレースを楽しめるようになりました。

于 2010-11-07T22:58:55.470 に答える