当客户端过早断开连接时,如何对烧瓶上的管道错误进行异常处理?

tia*_*lva 8 python ajax flask

我正在使用flask进行开发,而不是生产,我有一个ajax请求的视图,如下所示:

@application.route('/xyz/<var>/', methods=['GET'])
def getAjax(var):
    ...
    return render_template(...)
Run Code Online (Sandbox Code Playgroud)

我也threaded=true用于开发.每当我调用那个ajax请求然后只是关闭请求它的选项卡时,我会收到一个错误:

Traceback (most recent call last):   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 593, in process_request_thread
self.finish_request(request, client_address)   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 651, in __init__ 2015-07-07 09:46:09,430 127.0.0.1 - - [07/Jul/2015 09:46:09] "GET /xyz/List/ HTTP/1.1" 200 -
self.finish()   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 710, in finish
self.wfile.close()   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 279, in close
self.flush()   File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 303, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size]) error: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)

我可以有一个try: except块来捕获此异常吗?我尝试将所有getAjax函数的内容放在:

try:
    ...
except socket.error, e:
    logging.warn("socket error " + e)
Run Code Online (Sandbox Code Playgroud)

但它不起作用,我应该在哪里这样做?或者怎么样?

编辑:添加ajax调用

$.ajax({
    type: 'GET',
    url: '/xyz/' + var + '/',
    data: {
            ...
        },
    timeout: 2000,
    success: function(data) {
        ...
        },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        ...
        }
    });
Run Code Online (Sandbox Code Playgroud)

R P*_*gna 5

您遇到的问题是,通过使用Flask,您无法控制整个服务器堆栈,因此您无法捕获应用程序代码之外的错误.socket.error实际上是在Flask的内置开发服务器中传播的(它可能只是SocketServer的包装器,我不知道细节),并且因为它只是一个不适合生产使用的开发服务器,所以它不处理客户突然死亡的情况.

一般来说,这无关紧要.如果您使用Gunicorn或其他东西实际部署代码,那么WSGI容器将处理破坏的管道,而不需要您处理任何事情.您可以通过在本地容器中运行代码来测试这一点 - 尝试在您的计算机上安装Gunicorn,看看当您的应用程序代码在其包装器中运行时会发生什么.

如果你仍有问题,那么事情可能会变得复杂,因为问题可能出在许多不同的地方.Gevent只是处理这个特定的错误,所以如果你使用一个鲜为人知的WSGI容器,那么也许无法处理这个错误.或者它可能是他们正在使用的无法处理的东西.

一般来说,如果您以标准方式使用Web框架,则不必自行处理低级服务器错误.这就是您开始使用Web框架的原因.如果你试图推出自己的视频流或其他东西,那完全是另一种情况,但这似乎并非如此.