2015-06-23 8 views
5

Ich betreibe einen kleinen Webservice basierend auf Python-Kolben, wo ich eine kleine MySQL-Abfrage ausführen möchte. Wenn ich eine gültige Eingabe für meine SQL-Abfrage bekomme, funktioniert alles wie erwartet und ich bekomme den richtigen Wert zurück. Wenn jedoch der Wert nicht in der Datenbank gespeichert ist, erhalte ich eine TypeErrorFehlerbehandlung 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 

Ich habe versucht, in die Irre zu klopfen mir die Handhabung und den Code für mein Projekt zu verwenden, aber es scheint, als ob diese nicht richtig funktioniert.

#!/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) 

Grundsätzlich mag ich nur einen Wert zurückgeben, wenn alles richtig funktioniert und ich möchte nichts zurück, wenn es nicht vorzugsweise mit einer Fehlermeldung auf meinem Server ist. Wie kann ich die Fehlerbehandlung richtig nutzen?

BEARBEITEN Aktualisierter aktueller Code + Fehlermeldung.

+0

** außer TypeError, funktioniert e: ** nicht richtig? –

+0

@ kuket15 versuchte das auch schon mal. Habe danach einen ** ValueError ** erhalten: D Und als ich ** außer ValueError, e: ** danach benutzt habe, habe ich noch einen ** ValueError ** erhalten. Ich habe meine Frage jetzt bearbeitet, so dass Sie meinen aktuellen Status sehen können –

+1

Wenn es Flasche ist, die die Ausnahme abfängt, kann ValueError ('Ansicht-Funktion nicht zurückgeben ...') möglicherweise von keiner vorhandenen zurückgegeben werden. String im Gegenzug oder ein Ausnahme ValueError: Pass stattdessen zum Vergleich? Oder lies den Exception-Trap-Code in flask, wäre mein Vorschlag; um herauszufinden, wobt Ursache Kolben zu erhöhen. Darf deine Hände hier gebunden haben. –

Antwort

9

Erster Punkt: Sie haben zu viel Code in Ihrem Versuch/außer Block. Besser nutzen verschiedene try/erwarten Blöcke, wenn Sie zwei Aussagen (oder zwei Gruppen von Aussagen), die verschiedene Fehler erhöhen können:

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() 

Jetzt müssen Sie wirklich hier eine Typeerror fangen? Wenn Sie im Traceback lesen, werden Sie bemerken, dass Ihr Fehler vom Aufruf __getitem__() auf None kommt (nb: __getitem__() ist die Implementierung für den tiefgestellten Operator []), was bedeutet, dass, wenn Sie keine übereinstimmenden Zeilen haben cursor.fetchone()None zurückgibt, so können Sie nur testen Sie die Rückkehr von 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() 

Jetzt brauchen Sie wirklich MySQL Fehler hier zu fangen? Ihre Abfrage sollte gut getestet sein und es ist nur eine Leseoperation, also sollte sie nicht abstürzen - wenn Sie also hier etwas falsch machen, dann haben Sie offensichtlich ein größeres Problem, und Sie wollen es nicht unter dem Teppich verstecken. IOW: entweder die Ausnahmen log (mit dem Standard logging Paket und logger.exception()) und wieder heben sie oder einfach lassen sie verbreiten (und schließlich ein höheres Niveau haben componant nicht behandelte Ausnahmen von der Anmeldung kümmern):

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

finally: 
    conn.close() 

Und Schließlich: Die Art, wie Sie Ihre SQL-Abfrage erstellen, lautet utterly unsafe. Verwenden Sie sql Platzhalter stattdessen:

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