django broken-pipe

Django Broken pipe en modo Debug



broken-pipe (8)

Tengo django 1.3 en el servidor remoto detrás de Nginx.

Si ejecuto django con apache + mod_wsgi, puedo ver los errores en los archivos de registro de Apache. Está bien, pero me gustaría tenerlo en la consola.

Si ejecuto el propio servidor de desarrollo de django, recibo errores con stacktrace en la consola solo cuando DEBUG = False. En salidas de consola del modo DEBUG

Exception happened during processing of request from (..., ...) Traceback (most recent call last): File "/usr/local/python/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock self.process_request(request, client_address) File "/usr/local/python/lib/python2.7/SocketServer.py", line 310, in process_request self.finish_request(request, client_address) File "/usr/local/python/lib/python2.7/SocketServer.py", line 323, in finish_request self.RequestHandlerClass(request, client_address, self) File "/usr/local/python/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 570, in __init__ BaseHTTPRequestHandler.__init__(self, *args, **kwargs) File "/usr/local/python/lib/python2.7/SocketServer.py", line 641, in __init__ self.finish() File "/usr/local/python/lib/python2.7/SocketServer.py", line 694, in finish self.wfile.flush() File "/usr/local/python/lib/python2.7/socket.py", line 301, in flush self._sock.sendall(view[write_offset:write_offset+buffer_size]) error: [Errno 32] Broken pipe

Quiero averiguar por qué? ¿Por qué django solo envía Excepción sin nombre? ¿Por qué depende de la variable DEBUG?

Este error se produce principalmente en vistas externas cuando no tengo acceso al objeto de solicitud. Entonces no puedo atraparlo en middleware o usar el manejador de registro.

ACTUALIZAR. Me di cuenta de que si solicito el servidor django directamente, nunca obtengo Broken pipe. Entonces, ¿puede ocurrir el problema mientras Nginx proxy django?


Aquí hay una forma de evitar que se imprima el mensaje en stderr. Simplemente mono parche la función BaseServer.handle_error . Así es como lo hago:

def patch_broken_pipe_error(): """Monkey Patch BaseServer.handle_error to not write a stacktrace to stderr on broken pipe. https://.com/a/7913160""" import sys from SocketServer import BaseServer handle_error = BaseServer.handle_error def my_handle_error(self, request, client_address): type, err, tb = sys.exc_info() # there might be better ways to detect the specific erro if repr(err) == "error(32, ''Broken pipe'')": # you may ignore it... logging.getLogger(''mylog'').warn(err) else: handle_error(self, request, client_address) BaseServer.handle_error = my_handle_error patch_broken_pipe_error()


Directiva Nginx proxy_intercept_errors off; (deshabilitado por defecto) es lo que necesitaba


Esto no es realmente un problema con su sitio, más con el servidor dev de Django: vea este boleto de Django . Para decirlo sin rodeos, simplemente ignórelo ya que es un error conocido, y no será corregido.

En los comentarios de ese boleto se da una explicación bastante clara:

Según muchas fuentes, ''Broken Pipe'' es una peculiaridad normal del navegador. Por ejemplo, el navegador lee desde el socket y luego decide que la imagen que ha estado leyendo aparentemente no cambió. El navegador ahora esto (con fuerza) cierra la conexión porque no necesita más datos. El otro extremo de este socket (el servidor de ejecución python) ahora plantea una excepción de socket que le dice al programa que el cliente ''Rompió el socket''.


La directiva nginx (respuesta comprobada) no funcionó para mí, pero la combinación de parches de mono de Igor Katson y Michael_Scharf hizo:

def patch_broken_pipe_error(): """Monkey Patch BaseServer.handle_error to not write a stacktrace to stderr on broken pipe. http://.com/a/22618740/362702""" import sys from SocketServer import BaseServer from wsgiref import handlers handle_error = BaseServer.handle_error log_exception = handlers.BaseHandler.log_exception def is_broken_pipe_error(): type, err, tb = sys.exc_info() return repr(err) == "error(32, ''Broken pipe'')" def my_handle_error(self, request, client_address): if not is_broken_pipe_error(): handle_error(self, request, client_address) def my_log_exception(self, exc_info): if not is_broken_pipe_error(): log_exception(self, exc_info) BaseServer.handle_error = my_handle_error handlers.BaseHandler.log_exception = my_log_exception patch_broken_pipe_error()


Lo arreglé. Si usa enlaces, es decir, etiqueta de anclaje, dentro de la página, debe enfrentar el problema de "Tubería de Borken". Solo use dentro de la etiqueta de enlace href = ''#''. No deje el atributo href en blanco. Evitará ese tipo de error.


Me encontré con este problema también durante el uso de tilelite . En realidad, es causado por un error conocido y ahora corregido en Python. Puede resolver este problema aplicando el siguiente parche:

http://bugs.python.org/issue14574

De lo contrario, puede descargar una de las versiones más recientes de python.


Pude deshacerme de esto por

proxy_buffering off;

Esto detiene el almacenamiento en búfer de respuesta del servidor proxy. Esto lleva a otros problemas de la aplicación de back-end que se bloquea por mucho tiempo si el cliente tiene una conexión extremadamente lenta.

Para hacerlo condicional para solicitudes particulares, use X-Accel-Buffering = no en el encabezado de respuesta.


Se me ocurrió un parche de mono rápido y sucio (no sé si elimina cualquier error útil), que elimina este molesto error cuando se usa "./manage.py runserver" o se ejecutan pruebas de LiveServerTestCase.

Simplemente insértalo en cualquier parte de tu código, donde lo necesites:

# Monkeypatch python not to print "Broken Pipe" errors to stdout. import SocketServer from wsgiref import handlers SocketServer.BaseServer.handle_error = lambda *args, **kwargs: None handlers.BaseHandler.log_exception = lambda *args, **kwargs: None