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 のスタック トレースを楽しめるようになりました。