Exception Handling – Fehlerkategorien und ihre Behandlung
In der Softwareentwicklung ist die Unterscheidung nach Fehlerkategorien wichtig, da jeweils eine andere Behandlung erforderlich ist. Dieser Artikel bietet eine Übersicht.
Hinweis: Der Fokus des Artikels ist das Exception-Handling in Java. Die grundlegenden Prinzipien lassen sich jedoch auch auf andere Sprachen übertragen.
Bug |
Programmierfehler z.B. NullPointerException, ArrayIndexOutOfBounds, DivideByZero,… | Diese Fehler sollten bereits während der Entwicklung gefunden werden. Wenn sie dennoch auftreten: Fail fast, also Programmausführung sofort abbrechen! Fortführung führt zu Verschlimmerung der Situation und erschwert die Ursachensuche. |
---|---|---|
API-Nutzungsfehler |
falsche Verwendung der API durch den Client | Programmierfehler, aber nicht im Server sondern im Client. Im Server angefragte Aktion natürlich nicht ausführen und sofort hilfreiche Rückmeldung an API-Nutzer im Form einer definierten Exception / Fehlercode. Log-Level <= WARN |
Validierungsfehler |
falsche Benutzereingabe z.B. NumberFormatException, ParseException (sofern aus Benutzereingabe),… | Kein Fehler im eigentlichen Sinn. Fangen und hilfreiche Rückmeldung an Benutzer. Nicht loggen! Usability: Möglichst alle Validierungen in einem Block durchführen und Fehler gesammelt an den Aufrufenden zurück zu geben anstatt beim ersten Validierungsfehler abzubrechen. |
Vorübergehender Ausnahmezustand |
z.B. Thirdparty-Service nicht verfügbar, Netzwerkprobleme, etc. | Logging, (beschränkte Anzahl von) Retries nach jeweiliger Wartezeit, Ausfall der Gesamtanwendung durch zu viele erneute/auflaufende Requests von außerhalb durch Circuit-Breaker verhindern (sofern die Anwendung ohne das Teilsystem noch sinnvoll weiterlaufen kann) |
Behandelbarer Ausnahmezustand |
z.B. zwei Prozesse versuchen parallel eine Datei mit demselben Namen anzulegen | Spezifische Checked-Exception, auf die der Client reagieren kann z.B. indem er den Benutzer zu einer alternativen Eingabe auffordert oder automatisiert einen anderen Wert wählt (in unserem Beispiel die Wahl eines neuen Dateinamens durch den Benutzer oder automatisiertes Anhängen eines Zählers). |
Zusätzlich Hinweise zu den Fehlerkategorien:
Bug
Spezialfall: Nicht behandelbarer Ausnahmezustand, der aber kein Programmierfehler ist:
- Behandlung unterscheidet sich nicht von Bug, da eine Fortführung ebenfalls die Situation verschlimmert und die Ursachensuche erschwert.
- Die meisten Fehler sind aber sicherlich auf einen Programmierfehler zurückzuführen z.B. vergessenes Datenbank-Constraint oder fehlender Aufräumcode etc.
Fail fast:
- Fail fast via Spring Assert. Weitere hilfreiche Infos unter Spring Assert – Baeldung.com.
- Null-Asserts mit Objects.requireNonNull: Warum sollte man Objects.requireNonNull verwenden? – Stackoverflow.com
API-Nutzungsfehler
Log-Level:
- bei externen Clients kann WARN sinnvoll sein, um auf häufige Fehlbenutzung reagieren zu können (z.B. bessere Dokumentation, Erkennung versehentlicher API-Änderung)
- bei internen Clients würde ich Log-Level noch niedriger wählen
Validierungsfehler
Behandlung:
- Fangen und hilfreiche Rückmeldung an Benutzer d.h. Benutzer muss wissen, was er an seiner Eingabe ändern muss. Usability: möglichst alle Validierungen in einem Block durchführen und Fehler gesammelt an den Aufrufenden zurückgeben statt Ping-Pong…
- Nicht loggen! (oder höchstens TRACE / DEBUG)
Vorübergehender Ausnahmezustand
Behandlung:
- Logging
- (beschränkte Anzahl von) Retries nach jeweiliger Wartezeit
- Ausfall der Gesamtanwendung durch zu viele erneute/auflaufende Requests von außerhalb durch Circuit-Breaker verhindern (sofern die Anwendung ohne das Teilsystem noch Mehrwert bietet und gefahrlos weiterlaufen kann)
Circuit Breaker etwas detaillierter:
- Wenn ein Teilsystem ausfällt, blockiert ein Circuit Breaker die Anfragen für eine bestimmte Zeit, da sonst durch auflaufende Anfragen immer mehr Prozesse warten bis sie in Timeouts laufen und dadurch den Thread-Pool erschöpfen. Dadurch fällt dann die gesamte Anwendung aus. Wikipedia.org
Spring Retry:
Fazit
Bei der Behandlung von Fehlern ist es wichtig nach Art der Fehler zu unterscheiden, sie frühzeitig zu finden und Folgefehler zu vermeiden. Dabei ist es wichtig, durch hilfreiche Rückmeldung an den Nutzenden und gute Protokollierungspraxis Hilfestellung bei der Behandlung und/oder Ursachenanalyse zu bieten.
Bildnachweis:
– Das Titelbild zur Blogserie „Exception Handling“ basiert auf einer Grafik von mohamed_hassan auf Pixabay.