Exceção não atendida em flup
-
22-08-2019 - |
Pergunta
Estou enfrentando a temida "exceção não atendida" levantada por Flup. A parte triste é elevada no nível do servidor da web (LightTPD+Flup) e não no nível do aplicativo (Django). Portanto, nenhum e -mail 500 é levantado sobre onde está o problema.
Toda a nossa equipe se esforçou para limpar a base de código, no caso de quaisquer importações ambigitas e alguém desse tipo, apenas para eliminar as chances de levantar erros devido às importações ambíguas. E limpamos muitas coisas no código. Ainda é a mesma exceção.
Para ser franco, estou realmente frustrado com o manuseio de erros da Flup. Não diz nada a você. O pior de tudo é que mostra a mesma "exceção não tratada" para os usuários. Como faço para passar por isso?
Eu verifiquei os logs LightTPD. Tudo o que vejo é "erro de interface/conexão já fechado". Só ocorre quando meu Applicaiton está sendo executado no modo FCGI. Portanto, o problema é como o Flup está realmente lidando com o meu código (aplicativo). Como faço para passar por isso?
Eu verifiquei as alternativas para o FLUP, mas o Django depende de Flup explicitamente (que é mais uma restrição e me intrigou) (Referência: Django_src/django/core/servers/fastcgi.py Linha: 100/131)
Como faço para depurar (pelo menos) esse cenário e resolver o problema? Por favor, me ajude. O aplicativo caiu por 3 dias.
Solução
Eu não uso o LightTPD ou o FLUP, então isso não é uma resposta tanto quanto é dicas.
Começaria tentando executar o PDB em seu arquivo de aplicativo ou pelo menos escrever em um arquivo de log antes de ligar para o método Flup Server .run (). Dessa forma, você pode identificar o problema como estando no fastcgi ou no flup. Veja a seção chamada Depurador interativo do Python no wiki mod_wsgi. Isso pode lhe dar idéias sobre como fazer a mesma coisa com LightTPD e Flup.
Então, se o problema for flupido, você pegará a exceção no PDB e poderá depurar a partir daí.
Se o problema for LightTPD, você provavelmente terá algum tipo de problema em seu arquivo de configuração, ou talvez um problema com a maneira como o LightTPD foi construído. Talvez exista uma incompatibilidade da biblioteca do sistema entre o LightTP e seu módulo FastCGI?
Tente executar seu aplicativo no NGINX+FastCGI e veja se isso funciona ou pelo menos fornece melhores mensagens de erro.
Btw, o autor de Flup odeia o FCGI e nem usa mais flup... Eu recomendo mudar para nginx ou apache+mod_wsgi.
Outras dicas
Isso indica um erro bem antes de o Django iniciar a solicitação de processamento, como o erro de sintaxe no módulo Configurações. A maneira mais rápida de depurar esse problema é ativar o Fastcgi Debug. Esta é a linha 128 em django/core/servers/fastcgi.py
:
wsgi_opts['debug'] = False # Turn off flup tracebacks
Em seguida, execute o aplicativo com um django tão modificado, você verá o Traceback do Flup em toda a sua glória.
Eu atingi algo semelhante - temos o Django atrás do Nginx e permitimos que o Django lide com 500s - isso funciona 99,9% das vezes, mas quando estamos fazendo atualizações, às vezes essas "exceções não tratadas" passam.
O Django não substitui os ganchos de Flup para lidar com erros, então precisamos fazer isso nós mesmos e deixar o Django lidar com esses erros.
Primeira substituição flup.server.BaseFCGIServer.error
para erros através do Django. Em seguida, vamos dizer a Django para usar nosso modificado BaseFCGIServer
para ver esses erros.
Como o python é incrível, vamos trapacear e apenas machucar a coisa toda em um só lugar, django.core.servers.fastcgi.py
. Aqui vamos nós:
# 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
Agora você pode desfrutar de traços de pilha de django, mesmo para erros de nível de flupra!