EMZETT.
Login

Error Codes (Fehlercodes)

Kurz: Ein numerischer oder textueller Wert, der eine bestimmte Fehlerart eindeutig identifiziert — statt einer Exception gibt eine Funktion dabei einfach einen speziellen Rückgabewert zurück, der “Fehler” bedeutet.

Genauer: Fehlercodes waren vor allem in älteren oder systemnahen Sprachen üblich (z. B. Rückgabewert -1 oder null bei Misserfolg) und erfordern, dass der Aufrufer den Rückgabewert jedes Mal manuell prüft — wird das vergessen, läuft der Fehler unbemerkt weiter. Moderne, höhere Sprachen bevorzugen deshalb meist Exceptions, die nicht versehentlich ignoriert werden können.

Im Detail

int datei_oeffnen(char* pfad) {
    // gibt bei Erfolg einen positiven Datei-Handle zurück, bei Fehler -1
    if (!existiert(pfad)) return -1;
    // ...
}
 
int handle = datei_oeffnen("konfig.txt");
if (handle == -1) {
    // Fehler behandeln - ABER: was, wenn dieser Check vergessen wird?
}

Das Grundproblem von Fehlercodes: Sie sehen syntaktisch genauso aus wie jeder andere Rückgabewert. Nichts zwingt den Aufrufer, den Rückgabewert tatsächlich zu prüfen — wird die if-Prüfung vergessen, läuft das Programm einfach mit dem Fehlerwert (z. B. -1 als vermeintlicher Datei-Handle) weiter, als wäre nichts passiert, bis der Fehler irgendwo ganz anders im Code zu einem mysteriösen Folgefehler führt, weit entfernt von der eigentlichen Ursache. Dieses “stille Weiterlaufen mit ungültigen Daten” ist der Hauptkritikpunkt an Fehlercodes.

Ein zweites praktisches Problem: Der Wertebereich für “Fehler” und “gültiges Ergebnis” muss sich sauber trennen lassen. Bei einer Funktion, die eine beliebige Ganzzahl zurückgibt (auch negative Werte sind gültige Ergebnisse), lässt sich -1 nicht mehr eindeutig als “Fehler” markieren, ohne mit einem echten, gültigen Ergebniswert zu kollidieren — dann braucht es zusätzliche Mechanismen (z. B. einen separaten “hat Fehler?”-Ausgabeparameter).

Exceptions lösen beide Probleme strukturell: Ein Fehler unterbricht aktiv den normalen Kontrollfluss statt sich als unauffälliger Rückgabewert zu tarnen, und er kann jeden beliebigen zusätzlichen Kontext mittragen (eine Fehlermeldung, den Stack-Trace, die genaue Fehlerart als eigener Typ), ohne mit dem eigentlichen Rückgabewertebereich der Funktion zu kollidieren.

Trotzdem sind Fehlercodes nicht komplett veraltet: In sehr performance-kritischem, systemnahem Code (Betriebssystem-Kerne, Echtzeitsysteme) werden sie teils bewusst bevorzugt, weil das Werfen und Fangen von Exceptions in manchen Sprachen einen messbaren Laufzeit-Overhead hat. Auch viele moderne Sprachen (Go, Rust) haben bewusst wieder explizite Fehlerrückgabewerte statt klassischer Exceptions gewählt — allerdings mit sprachlichen Mitteln (z. B. Rusts Result-Typ), die das “versehentliche Ignorieren” verhindern, das klassischen Fehlercodes vorgeworfen wird.

Siehe auch: Exceptions, Errors