Exceptions - Richtige Anwendung und allg. Fragen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
neovanmatix
User
Beiträge: 19
Registriert: Samstag 28. Dezember 2013, 20:52

Hallo,

ich habe mittlerweile in Python3 ein relativ langes Script erstellt, dass mir Daten der seriellen Konsole abgreift, prüft, an ein PHP-WebScript übergibt und separat per PyMySQL in eine lokale Datenbank schreibt.

Bisher habe ich keine/kaum Exceptions verwendet, was ich nun gerne ändern möchte.

Mein Problem für den Einstieg ist aber gerade, in welchem Fall ich auf welche Exceptions prüfen muss. Klar kann ich jede meiner Funktionen einzeln in einem Script auslagern und mit komischen Daten füttern, oder Fehlerzustände bewusst herbeiführen um an den Namen der Exception zu kommen, die geworfen wurde - aber das deckt doch dann nicht alle Fälle ab; den manche Fehler (die ich nicht kenne) kann ich auch nicht bewusst herbeiführen.

Insbesondere bin ich etwas überfordert wenn es um Exceptions von dritten Librarys geht; etwa die pymysql-Lib für Python 3. Ich finde da schlicht keine Liste mit den möglichen Exceptions, die geworfen werden können - ein paar habe ich mir mal notiert:
pymysql.err.InternalError
pymysql.err.ProgrammingError
pymysql.err.OperationalError

Hierbei habe ich auch schon das erste Problem: Ich würde gerne die Fehlermeldung loggen; wenn ich aber eine der obigen Zeilen als Exception verwende - wie greife ich auf die ursprüngliche Fehlermeldung zu?

Habt ihr ein paar Tipps für mich?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

neovanmatix hat geschrieben:Ich würde gerne die Fehlermeldung loggen; wenn ich aber eine der obigen Zeilen als Exception verwende - wie greife ich auf die ursprüngliche Fehlermeldung zu?
Ganz kurz (nicht viel Zeit):

Code: Alles auswählen

>>> try:
	1 / 0
except ZeroDivisionError as e:
	print e

	
integer division or modulo by zero
jervis
User
Beiträge: 1
Registriert: Samstag 28. Dezember 2013, 23:17

Ich finde da schlicht keine Liste mit den möglichen Exceptions, die geworfen werden können
Hallo neovanmatix,

Du kannst dir in der Regel wie folgt anschauen was ein Modul zu bieten hat (ist zwar python 2.7, vorgehensweise sollte bei 3 aber die gleiche sein, denke ich):

Code: Alles auswählen

#!/usr/bin/env python
import pymysql
for i in pymysql.__dict__:
	print i
wenn du pymysql.__dict__ durch pymysql.__dict__.values() ersetzt werden dir direkt die Objekte zurückgegeben die du dann gegebenenfalls mit type() prüfen kannst.

Die Exceptions enden ja meist auf "Error", dürfte also kein Problem sein sie zu finden.

Wenn du mehr über eine Exception wissen willst kannst du natürlich ganz normal in den Docstring schauen:
>>> import pymysql
>>> print pymysql.InterfaceError.__doc__
Exception raised for errors that are related to the database
interface rather than the database itself.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@neovanmatix: Es gibt drei Arten von Exceptions. Bei der einen weiß ich, dass sie unter bestimmten Umständen auftreten, kann sie deshalb abfangen und das Programm wieder in einen konsistenten Zustand überführen, zum Beispiel:

Code: Alles auswählen

def input_int(text='Enter a number: '):
    while True:
        try:
            return int(input(text))
        except ValueError:
            print('Wrong input')
Hier weiß ich, bei der Umwandlung in ein »int« kann ein »ValueError« auftreten und reagiere entsprechend.
Wenn man nicht weiß, welche Exceptions geworfen werden können, ist es im Allgemeinen auch schwierig, das Programm wieder in einen konsistenten Zustand zu bringen. Wenn der konsistente Zustand bedeutet, informiere den Nutzer und mach weiter als ob nichts gewesen wäre, dann kann man eine beliebige Exception abfangen:

Code: Alles auswählen

try:
    do_something()
except Exception:
    logging.exception('error while do_something')
Hierbei ist es wichtig, dass die Meldung nicht kommentarlos verschluckt wird, weil auch Programmierfehler (NameError) mit erfasst werden.
Weiß ich nicht, wie ich auf eine Exception reagieren kann, oder es nicht möglich ist, das Programm wieder in einen Zustand zu versetzen mit dem es sinnvoll weiterarbeiten kann, dann darf man auch keine Exception abfangen.
BlackJack

@neovanmatix: Eigentlich sollten die Ausnahmen dokumentiert sein. Im Falle von DB Modulen die sich an die DB API 2.0 halten gibt es mindestens im entsprechenden PEP eine Liste welche Ausnahmen zu der API gehören: PEP 249 — Python Database API Specification v2.0, Exceptions.

Wenn Ausnahmen nicht dokumentiert sind, dann kannst Du nur raten und ausprobieren. Wobei wichtig ist, dass Du sowieso nur Ausnahmen behandeln solltest die Du auch sinnvoll behandeln kannst. Also ignorieren, oder auch Protokollieren und dann einfach weitermachen als wäre nichts passiert, kann man sich sowieso nur in den allerwenigsten Fällen erlauben. Denn das führt im Nachgang in der Regel zu weiteren Ausnahmen, oder noch schlimmer: zu Fehlern die sich dann unbemerkt einschleichen können, weil das Programm in sich nicht mehr in einem konsistenten Zustand ist.
BlackJack

Nachtrag: Wieso müsste man die Funktionen zum Testen in ein eigenes Skript kopieren? Man kann doch einfach Das Modul importieren in dem sie definiert sind. Und Grundsätzlich sind Unit-Tests auch keine schlechte Idee.
Antworten