Daniel Thoma: Rückgabewerte und Fehlerbehandlung allgemein bzw. am Beispiel

Beitrag lesen

Hallo frankx,

Dass überhaupt ein Fehler oder eine gravierende Ausnahme entstünde könnte ich in dem Fall ja abfangen, indem die lesende Klasse testet, ob ein File diese Namens überhaupt vorhanden ist (is_file()).

Ja, es gibt im wesentlichen drei Möglichkeiten, mit Ausnahmen umzugehen:
1. Die Ausnahme vorherzuerkennen
2. Spezielle Rückgabewerte
3. Exceptions

1. Kann manchmal sinnvoll sein, z.B. wenn es einfach deutlich effizienter ist, ein paar Voraussetzungen zu prüfen als erstmal mit einer größeren Berechnung zu beginnen und dann einen Fehler zu bekommen. Das Problem dabei ist, dass es nicht immer geht (jemand kann die Datei ja zwischen Abfrage und Öffnen löschen) und dass man es für jeden einzelnen Anwendungsfall überprüfen muss.
2. Dazu habe ich ja schon zwei Dinge gesagt, es wird umständlich, die Rückgabewerte auszuwerten und man muss die Fehlerbehandlung genau da machen, wo der Fehler auch auftritt.
3. Hat eigentlich nur Vorteile ;-)

Beispiel:

Mit vorherigem Überprüfen: funktioniert nicht wirklich):
if (file1.exists() && file2.exists() && file3.exists()) {
   data1 = parse(file1);
   data2 = parse(file2);
   data3 = parse(file3);
   ...
} else {
  // Fehlerbehandlung
}

Mit Rückgabewert:
data1 = parse(file1);
if (!data1) {
  // Fehlerbehandlung
}
data2 = parse(file2);
if (!data2) {
  // Fehlerbehandlung
}
data3 = parse(file3);
if (!data3) {
  // Fehlerbehandlung
}

Mit Exceptions:
try {
   data1 = parse(file1);
   data2 = parse(file2);
   data3 = parse(file3);
} catch (FileNotFound e) {
  // Fehlerbehandlung
}

Die Komplexität der Fehlerbehandlung bei 1. und 2. ist schon relativ hoch, bei einen etwas komplizierteren Ablauf wird es aber noch viel schlimmer. Im 2. Fall wird sogar der eigentliche Ablauf mit der Fehlerbehandlung vermischt. Muss man die Fehlerbehandlung sogar noch über mehrere Funktionen hinweg delegieren, bricht das totale Chaos aus.

Die Exceptions-Variante ist dagegen sehr simpel. Man braucht erstmal nur für jeden Fehlertyp (Wobei man durch Vererbung Fehler zusammenfassen kann und z.B. alle IO-Fehler gemeinsam behandeln) einen catch-Block und das war es. In PHP macht man die Fehlerunterscheidung wahrscheinlich nicht über mehrere Blöcke, sondern durch Abfrage des Typs. Das ist aber kein wesentlicher Unterschied.

Man muss einen Fehler auch nicht sofort verarbeiten sondern kann das in aufrufenden Funktionen tun, ohne dass man dafür wiederum Rückgabewerte verwenden muss.

Grüße

Daniel