Exceptions
Kurz: Ein Mechanismus, mit dem ein Programm auf unerwartete Fehler zur Laufzeit reagieren kann, ohne sofort komplett abzustürzen — ein Fehler wird “geworfen” und kann an anderer Stelle im Code gezielt “gefangen” und behandelt werden.
Genauer: Statt Rückgabewerte manuell auf Fehlercodes zu prüfen, unterbricht eine Exception den normalen Programmfluss und springt zum nächsten passenden Fehlerbehandlungsblock (try/catch). Das trennt den “Glücksfall”-Code vom Fehlerbehandlungscode und verhindert, dass ein übersehener Fehler unbemerkt weiterläuft. Bei mehreren möglichen Fehlerarten lassen sich unterschiedliche Behandlungsblöcke definieren.
Im Detail
try:
ergebnis = 10 / eingabe
except ZeroDivisionError:
print("Division durch Null ist nicht erlaubt")
except ValueError:
print("Eingabe war keine gültige Zahl")
else:
print("Erfolgreich berechnet:", ergebnis)
finally:
print("Dieser Block läuft IMMER, egal ob Fehler oder nicht")Der Ablauf beim “Werfen” einer Exception (englisch “throw” bzw. “raise”): Sobald ein Fehler auftritt, unterbricht die Laufzeitumgebung sofort die normale Ausführung an genau dieser Stelle und sucht — den Aufruf-Stack nach oben wandernd — nach dem nächsten passenden catch/except-Block, der diese Fehlerart behandeln kann. Findet sich keiner (die Exception “bricht durch” bis ganz nach oben), stürzt das Programm ab und zeigt einen Stack-Trace.
Dieses “Unterbrechen und nach oben weiterreichen” ist der entscheidende Vorteil gegenüber Fehlercodes als Rückgabewert: Ein Fehlercode kann versehentlich ignoriert werden (der Aufrufer prüft den Rückgabewert einfach nicht), und der Code läuft mit ungültigen Daten unbemerkt weiter. Eine Exception kann dagegen nicht “aus Versehen” ignoriert werden — entweder sie wird explizit behandelt, oder das Programm bricht sichtbar ab, was Fehler früher aufdeckt statt sie später, an einer ganz anderen Stelle, undurchsichtig eskalieren zu lassen.
Wichtig ist die Unterscheidung zwischen erwartbaren Fehlern (eine Datei existiert nicht, eine Nutzereingabe ist ungültig — Situationen, mit denen jedes robuste Programm rechnen sollte) und echten Programmierfehlern (ein Zugriff außerhalb der Array-Grenzen, ein Nullwert, wo nie einer sein sollte — Anzeichen eines Bugs im eigenen Code). Manche Sprachen (Java) unterscheiden das sogar explizit über “checked” (der Compiler zwingt zur Behandlung) und “unchecked” Exceptions (optional behandelbar, meist Programmierfehler).
Der finally-Block ist besonders wichtig für Aufräumarbeiten (eine Datei schließen, eine Verbindung freigeben), weil er garantiert ausgeführt wird — egal ob im try-Block alles glattlief, eine Exception auftrat, oder sogar ein vorzeitiges return mitten im try-Block steckte. try-with-resources automatisiert genau diesen Anwendungsfall für Ressourcen, die geschlossen werden müssen.
Siehe auch: Errors, Multiple Exceptions, try-with-resources