2015-06-23 7 views
5

Sto eseguendo un piccolo webservice basato su una boccetta Python, dove voglio eseguire una piccola query MySQL. Quando ottengo un input valido per la mia query SQL, tutto funziona come previsto e ottengo il giusto valore. Tuttavia, se il valore non è memorizzato nel database ricevo un TypeErrorGestione degli errori in Python-MySQL

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__ 
    return self.wsgi_app(environ, start_response) 
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app 
    response = self.make_response(self.handle_exception(e)) 
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception 
    reraise(exc_type, exc_value, tb) 
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app 
    response = self.full_dispatch_request() 
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1478, in full_dispatch_request 
    response = self.make_response(rv) 
    File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1566, in make_response 
    raise ValueError('View function did not return a response') 
ValueError: View function did not return a response 

ho cercato di attingere errore io movimentazione e utilizzare questo codice per il mio progetto, ma sembra che questo non funziona correttamente.

#!/usr/bin/python 

from flask import Flask, request 
import MySQLdb 

import json 

app = Flask(__name__) 


@app.route("/get_user", methods=["POST"]) 
def get_user(): 
    data = json.loads(request.data) 
    email = data["email"] 

    sql = "SELECT userid FROM oc_preferences WHERE configkey='email' AND configvalue LIKE '" + email + "%';"; 

    conn = MySQLdb.connect(host="localhost", 
          user="root", 
          passwd="ubuntu", 
          db="owncloud", 
          port=3306) 
    curs = conn.cursor() 

    try: 
     curs.execute(sql) 
     user = curs.fetchone()[0] 
     return user 
    except MySQLdb.Error, e: 
     try: 
      print "MySQL Error [%d]: %s" % (e.args[0], e.args[1]) 
      return None 
     except IndexError: 
      print "MySQL Error: %s" % str(e) 
      return None 
    except TypeError, e: 
     print(e) 
     return None 
    except ValueError, e: 
     print(e) 
     return None 
    finally: 
     curs.close() 
     conn.close() 

if __name__ == "__main__": 
    app.run(host="0.0.0.0", port=5000, debug=True) 

Fondamentalmente voglio solo restituire un valore, quando tutto funziona correttamente e voglio tornare nulla se non è preferibilmente con un messaggio di errore sul mio server. Come posso usare la gestione degli errori in modo corretto?

EDIT Codice aggiornato aggiornato + messaggio di errore.

+0

** eccetto TypeError, e: ** non funziona correttamente? –

+0

@ kuket15 ci ha provato anche prima. Ricevuto un ** ValueError ** dopo quello: D E quando ho usato ** tranne ValueError, e: ** dopo, ho ancora ricevuto un ** ValueError **. Ho modificato la mia domanda ora, in modo da poter vedere il mio stato attuale –

+1

Se si tratta di una beuta che cattura l'eccezione, ValueError ('La funzione di vista non ha restituito ...') potrebbe essere sollevata da qualsiasi ritorno Nessuno esistente .. prova un manichino- stringa in risposta o un eccezione ValueError: passare invece per il confronto? O leggere il codice del trap di eccezione nel pallone, sarebbe il mio suggerimento; per scoprire che il pallone causa wobt da sollevare. Potrebbe avere le mani legate qui. –

risposta

9

Primo punto: hai troppo codice nel tuo tentativo/tranne il blocco. Meglio usare try distinto/aspettarsi blocchi quando si hanno due affermazioni (o due gruppi di istruzioni) che possono aumentare diversi errori:

try: 
    try: 
     curs.execute(sql) 
     # NB : you won't get an IntegrityError when reading 
    except (MySQLdb.Error, MySQLdb.Warning) as e: 
     print(e) 
     return None 

    try: 
     user = curs.fetchone()[0] 
     return user 
    except TypeError as e: 
     print(e) 
     return None 

finally: 
    conn.close() 

Ora Hai davvero di prendere un TypeError qui? Se leggi al traceback, noterai che il tuo errore deriva dal chiamare __getitem__() su None (nb: __getitem__() (nb: []), che significa che se non hai righe corrispondenti cursor.fetchone() restituisce None, quindi puoi solo testare il ritorno di currsor.fetchone():

try: 
    try: 
     curs.execute(sql) 
     # NB : you won't get an IntegrityError when reading 
    except (MySQLdb.Error, MySQLdb.Warning) as e: 
     print(e) 
     return None 

    row = curs.fetchone() 
    if row: 
     return row[0] 
    return None 

finally: 
    conn.close() 

Ora non si ha realmente bisogno di prendere MySQL errori qui? La tua query dovrebbe essere ben testata ed è solo un'operazione di lettura quindi non dovrebbe bloccarsi, quindi se hai qualcosa che non va qui allora hai ovviamente un problema più grande e non vuoi nasconderlo sotto il tappeto. IOW: o registrare le eccezioni (utilizzando il pacchetto standard logging e logger.exception()) e re-raise o più semplicemente lasciarli propagare (e alla fine hanno un più alto livello componant prendersi cura di registrare le eccezioni non gestite):

try: 
    curs.execute(sql) 
    row = curs.fetchone() 
    if row: 
     return row[0] 
    return None 

finally: 
    conn.close() 

E infine: il modo in cui costruisci la tua query sql è utterly unsafe. Utilizzare invece segnaposto sql:

q = "%s%%" % data["email"].strip() 
sql = "select userid from oc_preferences where configkey='email' and configvalue like %s" 
cursor.execute(sql, [q,])