Eccezione non gestita in Flup
-
22-08-2019 - |
Domanda
Sono di fronte il temuto "Eccezione non gestita" sollevata da Flup. La parte triste è posizione sollevata al server web (lighttpd + flup) livello e non a livello di applicazione (Django). Quindi nessun 500 e-mail è sollevata su dove sia il problema.
Il nostro team ha lottato duramente per la pulizia del codice di base, in caso di eventuali importazioni ambiguo e qualcuno del genere, solo per essere eliminare le possibilità di raccolta di errori a causa delle importazioni ambigue. E abbiamo ripulito molte cose nel codice. Sempre la stessa eccezione.
Per essere franco Sono veramente frustrato con la gestione degli errori di Flup. Non si dice nulla. Peggio di tutto, si mostra lo stesso "Eccezione non gestita" per gli Utenti. Come faccio a passare questo?
Ho controllato i registri lighttpd. Tutto quello che vedo è "Errore interfaccia / connessione già chiuso." Il suo solo che si verificano quando il mio applicaiton è in esecuzione in modalità fcgi. Quindi il problema è con il modo flup è in realtà a che fare con il mio codice (applicazione). Come faccio a passare questo?
Ho controllato per alternative per flup, ma Django dipende da flup esplicitamente (che è un altro limite, e mi ha perplesso) (Riferimento: django_src / django / core / server / Linea fastcgi.py: 100/131)
Come faccio il debug (almeno) questo scenario e risolvere il problema? Per favore aiutatemi. L'applicazione è stato giù per 3 giorni.
Soluzione
Non faccio uso lighttpd o flup, quindi questa non è una risposta tanto quanto lo è suggerimenti.
Mi piacerebbe iniziare dal tentativo di eseguire PDB nel file app, o per lo meno la scrittura di un file di log prima di chiamare il metodo di server di .run flup (). In questo modo è possibile identificare il problema come in FastCGI o in flup. Vedere la sezione chiamata Python Interactive Debugger nel wiki mod_wsgi. Questo potrebbe darvi idee su come fare la stessa cosa con lighttpd e flup.
Quindi, se il problema è flup ti cattura l'eccezione nel PPB e possibile eseguire il debug da lì.
Se il problema è lighttpd allora probabilmente hanno un qualche tipo di problema nel file di configurazione, o forse un problema con il modo in cui è stato costruito lighttpd. Forse c'è una mancata corrispondenza tra la libreria di sistema lighttp e il suo modulo FastCGI?
Provare a eseguire la vostra applicazione sotto nginx + FastCGI e vedere se funziona o almeno ti dà migliori messaggi di errore.
A proposito, l'autore di flup odia fcgi e non ha nemmeno usare flup più ... mi consiglia di passare a nginx o Apache + mod_wsgi.
Altri suggerimenti
Questo indica errore ben prima Django inizia l'elaborazione della richiesta, come errore di sintassi nel modulo impostazioni. Il modo più veloce per eseguire il debug di tale problema è quello di trasformare il FastCGI di debug. Questa è la linea 128 in django/core/servers/fastcgi.py
:
wsgi_opts['debug'] = False # Turn off flup tracebacks
Quindi eseguire l'applicazione con quali Django modificata, Vedrete il traceback Flup in tutta la sua gloria.
ho colpito qualcosa di simile - abbiamo Django dietro Nginx, e permettiamo Django per gestire 500s -. Funziona il 99,9% del tempo, ma quando stiamo facendo aggiornamenti, a volte queste "eccezioni non gestite" scivolare attraverso
Django non sovrascrive i ganci di flup di gestione degli errori, quindi avremo bisogno di farlo noi stessi, e lasciare che Django gestire questi errori.
Prima di override flup.server.BaseFCGIServer.error
ad errori attraverso Django. Poi vi racconteremo Django di usare la nostra BaseFCGIServer
modificato per vedere quegli errori.
Dato che Python è impressionante, ci imbrogliare e solo monkeypatch il tutto in un unico luogo, django.core.servers.fastcgi.py
. Ecco come fare:
# 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
Ora si può godere Django pila ripercorre anche per errori di livello flup!