Vortrag Exceptions

  • Kontext:
    • wie kann man mit fehlern umgehen
      • fehler(un)freundliche systeme
      • bandbreite der fehler von lethal bis nervig, bis "man kann daraus etwas lernen" (feedback?)
      • Folgekosten abschätzen
      • was will man eigentlich: will man etwas für die Benutzer tun, oder diese in die Lage versetzen Selbst etwas zu tun.
    • soweit ansprechen - selber weiterbilden?
      • evtl., man sieht am code wie der Programmmierer drauf ist, man soll sich selber weiterentwickeln, der Code folgt dieser entwicklung dann.

Vortrag Felix

Bandbreite von Fehlern

Klar werden, was Folgen von Fehlern sind Nervig -> beim Flugzeug fallen im Flug die Motoren aus und Anzeige falsch Fehlerbehandlung kann auch wieder Fehler enthalten

Was will man erreichen? Fehler selber behandeln oder Benutzer bekommt genug Informationen, um den Fehler selbst zu beheben.

Letzte Version wesentlich mächtiger, erfordert aber mehr vom Benutzer. Erste Version manchmal problematisch.

Dumm Dialogbox mit Fehler -5123 bringt nichts, weil der Anwender weder den Fehler beheben kann noch das Programm den Fehler behoben werden kann.

Man kann idR für die Benutzer den Fehler selbst nicht beheben, sondern ihnen meist nur Tools an die Hand geben, um den Fehler zu beheben.


Fehlerbehandlung:

  1. Standardfehler: Datei nicht vorhanden
  2. Print Stack Trace
  3. RunTimeException

spezifische Exceptions behandeln


Exceptions / Fehlerbehandlung


In jedem Programm treten Fehler auf. Die ideale Zeit, um Fehler zu entdecken ist, wenn das Programm kompiliert wird: Nur ein Mensch (der Entwickler selbst) wird mit dem Fehler konfrontiert und hat auch die besten Möglichkeiten, den Fehler zu beheben.

Unglücklicherweise treten manche Fehler erst bei der Ausführung auf. Fehlerklasse: Code, der mit externen Systemen (Netzwerk, Dateisystem) kommuniziert oder sehr dynamischer OO-Code, bei dem der Compiler nicht mehr alles prüfen kann.

Ein gutes Programm verlässt sich nicht darauf, dass schon keine Fehler auftreten werden, sondern fängt Fehler ab. Nach einem Fehler kann das Programm nicht weiter ausgeführt werden, als sei nichts geschehen. Andernfalls würden nachfolgende Operationen vermutlich völlig unvorhersehbares Verhalten zeigen.


In C und anderen Sprachen wurde die Fehlerentdeckung so gehandhabt, dass nahezu alle Funktionen einen Rückgabewert haben, der dann geprüft wird.

Wenn man alle Fehler immer abprüft hat man 90% und mehr fehler-prüf-code und 10% oder weniger tatsächlichen Algorythmus. Das hat dann sehr wenig mit mit dem schönen Pseudocode aus Vorlesungen zu tun.

Zudem ergibt sich das Problem, dass die Fehlerwerte nur durch Konvention bestimmt, nicht aber durch die Sprache vorgegeben sind. -1 ist z.B. ein häufiger Fehlerwert, manchmal ist es aber auch 0.

Zudem treten Fehler idR relativ selten auf. Ständig auf seltene Fehler zu prüfen, macht daher wenig Sinn.

Daher ist es besser, den Fehlerbehandlungscode an einer Stelle zu haben und ihn so auch von den eigentlichen Algorithmen zu trennen.

Beispiel (aus Java?)

  • So geht das konkret in Java:
try {
       // hier kommt der code der
       // einen Fehler produzieren kann
} catch (Exception anException) {
       // statt Exception kann man auch eine
       // konkrete Exception wie IndexOutOfBoundsException
       // direkt angeben. Generell macht das aber Eclipse.

       // Hier kommt dann der eigentliche Fehlerbehandlungscode
       // der oft nur einfach angibt wo der fehler genau passiert ist,
       // da das beim Debuggen gewaltig helfen kann.
       anException.printStackTrace();
}


  • Wann Exceptions, wann Rückgabewerte?

Exceptions geben Fehler oder, wie der name schon sagt Ausnahmesituationen. Das heist, wenn ich wissen will ob ein array ein Objekt enthält, dann habe ich eine Funktion die mir das sagt und nicht eine funktion die mir das objekt zurückgibt wenn es da ist und ansonsten eine Exception wirft.

Es ist also falsch Exceptions zu verwenden um den Kontrollfluss zu steuern:

Beispiel: Wenn ich sowas seh werd ich zum Hirsch!

try {
       int sum = 0, i = 0;
       while (true) {
               sum += anArray[i++];
       }
} catch (IndexOutOfBoundsException expected) {}
// und weiter gehts....

Daher gibt "aString.indexOf(searchedString)" -1 zurück wenn "searchedString" nicht in "aString" enthalten ist - schlicht weil man indexOf() dazu verwenden soll um herauszufinden ob "aString" "searchedString" enthät oder nicht. (Hier noch ein Beispiel?)

(Anmerkung: Checked Exceptions vs. Runtime Exceptions würde ich wenn überhaupt nur ansprechen aber nicht vertiefen.)



Exceptions haben noch einen Vorteil ggü Rückgabewerten: Wenn das aktuelle Modul nicht weiß, wie der Fehler (Exception) zu behandeln ist (kein catch Block), kann der Fehler an den Aufrufer der Methode weitergereicht werden.

Beispiel: throw


In Java gibt es nicht nur "Standard-Exceptions", sondern viele differenzierte Subklassen, die alle von Exception erben, z.B. FileNotFoundException oder UnknownHostException. diese können einzeln gefangen werden. Alle Exceptions erben von Exception, daher kann man auch einfach alle fangen.