2009-02-09 13 views
6

Me enfrento a la temida "Excepción no controlada" planteada por Flup. La parte triste es que se plantea en el nivel del servidor web (lighttpd + flup) y no en el nivel de la aplicación (Django). Entonces, no se generan 500 correos electrónicos sobre dónde está el problema.Excepción no controlada en Flup

Todo nuestro equipo luchó duro para limpiar la base de código, en caso de importaciones ambiguas y algunas de ese tipo, solo para eliminar las posibilidades de generar errores debido a las importaciones ambiguas. Y limpiamos muchas cosas en el código. Todavía la misma excepción.

Para ser sincero, estoy realmente frustrado con el manejo de errores de Flup. No te dice nada. Lo peor de todo es que muestra la misma "excepción no controlada" a los usuarios. ¿Cómo puedo pasar esto?

Revisé los registros lighttpd. Todo lo que veo es "Error de interfaz/conexión ya cerrada". Solo ocurre cuando mi aplicación se ejecuta en modo FCGI. Entonces, el problema está en cómo flup en realidad está lidiando con mi código (aplicación). ¿Cómo puedo pasar esto?

he comprobado de alternativas para flup, pero Django depende de flup explícitamente (que es uno más restricción, y me desconcertado) (Referencia: django_src/django/core/servidores/línea fastcgi.py: 100/131)

¿Cómo depuro (al menos) este escenario y soluciono el problema? Por favor, ayúdame. La aplicación ha estado inactiva durante 3 días.

Respuesta

3

No uso lighttpd o flup, así que esta no es una respuesta tanto como lo es.

Comenzaré por tratar de ejecutar PDB en el archivo de tu aplicación, o al menos escribir en un archivo de registro antes de llamar al método flr del servidor .run(). De esta forma, puede identificar el problema como estar en fastcgi o en flup. Consulte la sección llamada Python Interactive Debugger en la wiki de mod_wsgi. Eso podría darte ideas sobre cómo hacer lo mismo con lighttpd y flup.

Luego, si el problema es falso, detectará la excepción en pdb y podrá depurar desde allí.

Si el problema es lighttpd entonces es probable que tenga algún tipo de problema en su archivo de configuración, o tal vez un problema con la forma en que se construyó lighttpd. ¿Tal vez hay una discrepancia en la biblioteca del sistema entre lighttp y su módulo fastcgi?

Intente ejecutar su aplicación en nginx + fastcgi y vea si eso funciona o al menos le da mejores mensajes de error.

Btw, el autor de flup hates FCGI and doesn't even use flup anymore ... Yo recomendaría cambiar a nginx o apache + mod_wsgi.

+0

Gracias Van. Lo entiendo completamente y actualmente estoy interesado en wsgi internals y leyendo sobre nginx. Pero. ¿Cuál es su comentario sobre la dependencia de django en flup? (He mencionado fastcgi.py en mi pregunta. Échele un vistazo) –

+0

Para ejecutar Django con nginx, necesita vincular WSGI a FastCGI, que es la tarea de Flup en realidad. – zgoda

+0

Van & Zgoda, Como puede entender por la descripción de mi pregunta, estoy bastante descontento con el Flup (y el manejo de errores/excepciones y cómo se muestra a los usuarios del sitio). ¿Hay alguna alternativa al uso de Flup? (¿Y qué pasa con la dependencia de FastCgi.py flup de django?) ¡Depende de mi pregunta! –

9

Esto indica un error mucho antes de que Django comience a procesar la solicitud, como un error de sintaxis en el módulo de configuración. La forma más rápida de solucionar este problema es activar la depuración FastCGI. Esta es la línea 128 en django/core/servers/fastcgi.py:

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

A continuación, ejecute la aplicación con tales Django modificado, verá el rastreo Flup en todo su esplendor.

6

Me tocó algo similar - tenemos a Django detrás de NGINX, y permitimos que Django maneje 500s - esto funciona el 99.9% del tiempo, pero cuando estamos haciendo actualizaciones, algunas veces estas "Excepciones no controladas" se filtran.

Django no anula los ganchos de flup para el manejo de errores, por lo que tendremos que hacerlo nosotros mismos, y dejar que Django maneje estos errores.

Primero anule flup.server.BaseFCGIServer.error a los errores a través de Django. Luego le diremos a Django que use nuestro BaseFCGIServer modificado para ver esos errores.

Dado que Python es increíble, haremos trampas y solo monopatch todo en un solo lugar, django.core.servers.fastcgi.py. Aquí vamos:

# 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 

¡Ahora puedes disfrutar de los rastros de pila de Django incluso para los errores de nivel de inversión!

+0

Esa es una respuesta increíble. Gracias jbox. –

+0

¡Quiero +++ esta respuesta! Ahora veo toda la información que necesito en lugar de solo 'Excepción no controlada'. – Octopus

Cuestiones relacionadas