我在Nginx后面的远程服务器上有django 1.3。
如果我用apache + mod_wsgi运行django,我可以在apache日志文件中查看错误。没关系,但我想在控制台中使用。
如果我运行django自己的开发服务器,只有在DEBUG = False时才会在控制台中出现stacktrace错误。在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
我想弄明白为什么?为什么django只输出未命名的Exception?为什么它依赖于DEBUG变量。
当我无法访问请求对象时,此错误主要发生在视图外部。所以我无法在中间件或使用日志记录处理程序中捕获它。
更新。我注意到如果我直接向django服务器请求我永远不会破坏管道。因此,当Nginx代理django时,问题可能会发生吗?
答案 0 :(得分:55)
这对您的网站来说不是一个问题,更多的是使用Django devserver:请参阅此Django ticket。直截了当地说,只是忽略它,因为它是一个已知的错误,并且不会被修复。
在该票的评论中,给出了一个非常明确的解释:
根据许多消息来源,'Broken Pipe'是一个普通的浏览器怪癖。例如,浏览器从套接字读取,然后决定它正在阅读的图像显然没有改变。浏览器现在(强制)关闭连接,因为它不需要更多数据。这个套接字的另一端(python runserver)现在引发一个套接字异常,告诉程序客户端“破坏套接字管道”。
答案 1 :(得分:8)
Nginx指令proxy_intercept_errors off;
(默认情况下禁用)是我需要的
答案 2 :(得分:6)
nginx指令(已检查答案)对我没有用,但是结合Igor Katson和Michael_Scharf的猴子补丁做了:
def patch_broken_pipe_error():
"""Monkey Patch BaseServer.handle_error to not write
a stacktrace to stderr on broken pipe.
http://stackoverflow.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()
答案 3 :(得分:4)
这是一种阻止将消息打印到stderr的方法。只需monkey patch
BaseServer.handle_error
功能。我就是这样做的:
def patch_broken_pipe_error():
"""Monkey Patch BaseServer.handle_error to not write
a stacktrace to stderr on broken pipe.
https://stackoverflow.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()
答案 4 :(得分:2)
我能够通过
摆脱这个proxy_buffering off;
这会停止代理服务器的响应缓冲。如果客户端连接速度极慢,这会导致后端应用程序的其他问题长时间锁定。
要使其成为特定请求的条件,请在响应标头中使用 X-Accel-Buffering = no 。
答案 5 :(得分:2)
我想出了一个快速而又脏的猴子补丁(我不知道它是否会出现任何有用的错误),当使用“./manage.py runserver”或运行LiveServerTestCase测试时,它会摆脱这个恼人的错误。 / p>
只需将其插入代码中的任何位置即可:
# 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
答案 6 :(得分:0)
我在使用tilelite时遇到了这个问题。它实际上是由python中已知的,现在已修复的错误引起的。您可以通过应用以下修补程序来解决此问题:
http://bugs.python.org/issue14574
否则,你可以下载一个更新的python版本。
答案 7 :(得分:0)
我修好了。 如果您在页面内使用链接,即锚标记,则必须面对" Borken Pipe"问题。只需在链接标记内使用href ='#'。不要将href属性留空。它将避免这种类型的错误。