2015-07-07 2 views
7

Sto usando pallone per lo sviluppo, non la produzione, e ho una visione per una richiesta ajax, qualcosa di simile:come fare un'eccezione per errori di pipe rotte sul pallone, quando il client si disconnette prematuramente?

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

sto utilizzando anche threaded=true per lo sviluppo. Ogni volta che io chiamo la richiesta Ajax e poi basta chiudere la scheda che lo ha richiesto ottengo un errore:

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 

Posso avere un blocco try: except per catturare questa eccezione? Ho provato a mettere tutto il contenuto della funzione getAjax su:

try: 
    ... 
except socket.error, e: 
    logging.warn("socket error " + e) 

Ma non sta funzionando, in cui devo fare questo? o come?

EDIT: aggiungendo la chiamata AJAX

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

Avete controllato [questa risposta] (http://stackoverflow.com/questions/22560259/error-errno-32-broken-pipe)? E considera di pubblicare il tuo codice Ajax se vuoi più feedback. – doru

+0

Bene, la risposta selezionata non sembra darmi ulteriori informazioni, poiché so già che l'errore è causato dal fatto che il cliente è assente per ricevere la risposta. Ma non sono sicuro del significato del poster con la modifica: dicendo che non ha inviato la risposta di Python. – tiagosilva

+0

Hai provato ad aumentare il 'timeout' a 20000, ad esempio? – doru

risposta

5

Il problema che hai è che utilizzando Flask non sei in controllo del tuo stack server completo, e quindi non è possibile rilevare gli errori che si presentano al di fuori di il tuo codice di applicazione. Il socket.error si sta effettivamente propagando nel server di sviluppo integrato di Flask (che potrebbe essere solo un wrapper attorno a SocketServer, non conosco i dettagli), e poiché è solo un server di sviluppo non pensato per l'uso in produzione, non sta gestendo il caso che un cliente muore improvvisamente.

Generalmente, questo non dovrebbe importare. Se dovessi effettivamente distribuire il tuo codice usando Gunicorn o qualcosa del genere, allora il contenitore WSGI gestirà il tubo rotto senza nulla da te. Puoi testare questo eseguendo il codice in un contenitore di questo tipo localmente - prova a installare Gunicorn sul tuo computer e a vedere cosa succede quando il codice dell'app viene eseguito nel suo involucro.

Se il problema persiste, le cose potrebbero complicarsi perché il problema potrebbe essere in molti luoghi diversi. Gevent just got to handling this particular error, quindi se si sta utilizzando un contenitore WSGI meno noto, potrebbe non essere in grado di gestire questo errore. O potrebbe essere qualcosa sono utilizzando che non può gestire questo.

In generale, se si utilizza un framework Web in un modo standard, non è necessario gestire gli errori del server di basso livello da soli. Ecco perché stai usando il framework web per cominciare. Se stai provando a far girare il tuo video streaming o qualcosa del genere, questo è completamente un altro caso, ma non sembra essere il caso qui.

+0

Grazie, sto effettivamente eseguendo il codice in produzione dietro gunicorn, quando la stessa cosa accade in produzione non c'è un errore per dire. La parte di errore della chiamata ajax viene ancora chiamata ma {textStatus} è 'errore', {errorThrown} è vuoto. Da quello che dici ho capito che questo non dovrebbe accadere. Ho ragione a ritenerlo? – tiagosilva

+0

Bene, l'errore del server sicuramente non dovrebbe accadere, ed è bene che non lo sia. Sono sorpreso che il codice Javascript sia in giro abbastanza a lungo da eseguire il codice di gestione degli errori se stai chiudendo la scheda/navigando, comunque. Potrebbe essere solo una parte del salvataggio per la chiamata di funzione. Vorrei provarlo con diversi browser e vedere se si ottiene lo stesso comportamento. Se nulla viene influenzato negativamente, probabilmente non mi preoccuperei di un errore del browser durante l'uscita. –