Design der Ausnahmehierarchie

9

In meinem Unternehmen erstellen wir eine Webanwendung mit mehreren zentralen Diensten, die wir selbst entwerfen und dann als Schnittstellen angeben. Das heißt, die Schnittstellen sind anwendungsspezifisch und werden dann mit Bibliotheken von Drittanbietern implementiert, die wir im Laufe der Zeit ändern können. Bei Ausnahmen habe ich festgestellt, dass die von unseren Diensten ausgelösten Ausnahmen unsere eigenen anwendungsspezifischen Ausnahmen sein sollten, im Gegensatz zu implementierungsspezifischen Ausnahmen.

Jetzt frage ich mich, wie unsere Ausnahmen strukturiert und miteinander in Beziehung gesetzt werden sollen.

Betrachten Sie zunächst eine generische Ausnahme MyAppException. Diese Ausnahme weist darauf hin, dass etwas Unerwartetes schief gelaufen ist. Das Beste, was wir tun können, ist, dem Benutzer eine Meldung anzuzeigen, dass etwas schief gelaufen ist und wir daran arbeiten. Der Fehler könnte sein, dass die Datenbank abgestürzt ist oder etwas Ähnliches. Diese Ausnahme würde so ziemlich von allen Methoden ausgelöst, die mit der Datenbank arbeiten.

Zweitens betrachten Sie eine Ausnahme MyAppDuplicateException. Diese Ausnahme würde darauf hinweisen, dass der Benutzer versucht hat, etwas in der bereits vorhandenen Datenbank zu speichern. Hier können wir eine viel spezifischere Fehlermeldung anzeigen, und diese Ausnahme wird nur von den Methoden ausgelöst, die Datenbankzeilen einfügen oder aktualisieren.

Die Anwendung kann auch andere Ausnahmen enthalten, die denen MyAppDuplicateExceptionfür andere erwartete Fehlersituationen ähneln. Ex MyAppNotFoundExceptionetc ...

Nun zu meinen Fragen:

  1. Sollten sich die anderen Ausnahmen erstrecken MyAppException? Ich sehe eigentlich keinen Grund dafür, ich habe es gerade an vielen Orten gesehen und frage mich, ob es einen Zweck hat. Der Nachteil davon ist, wie ich sehe, dass sich eine try / catch-Anweisung in diesem Fall nicht um die spezifische Ausnahme kümmern muss. Es kann nur die oberste Ausnahme abfangen und muss aus diesem Grund nicht den spezifischen Fehler behandeln, der so ziemlich der Grund für die spezifische Ausnahme war.
  2. Wenn sich die anderen Ausnahmen nicht erstrecken MyAppException, sollte MyAppExceptionein java.lang.RuntimeException? Dies würde nicht erfordern, Code auszuführen, um ihn abzufangen, was für mich natürlich klingt, da der Punkt der Ausnahme darin besteht, zu sagen, dass etwas Unbekanntes passiert ist und der ausführende Code nicht erwartet wird, damit umgehen zu können. Der Code am Einstiegspunkt der Anforderung kann weiterhin eine try / catch-Anweisung enthalten, die abfängt MyAppExceptionund sicherstellt, dass dem Benutzer eine Nachricht angezeigt wird.

bearbeiten Es steht außer Frage, ob die spezifischen Ausnahmen wie MyAppDuplicateExceptionüberprüft werden sollen oder nicht, die auf jeden Fall überprüft werden sollen.

Ludwig Magnusson
quelle

Antworten:

9
  1. Manchmal möchten Sie eine bestimmte Art von Ausnahme MyAppDuplicateExceptionabfangen (z MyAppException. B. ) und manchmal möchten Sie eine ganze Kategorie von Ausnahmen abfangen (z . B. ). Durch die MyAppDuplicateExceptionErweiterung geben MyAppExceptionSie dem aufrufenden Code etwas mehr Flexibilität im Umgang mit den verschiedenen Ausnahmen.
  2. Der beste Rat, den ich dazu gehört habe, ist, dass Sie im Allgemeinen eine aktivierte Ausnahme auslösen sollten, wenn Ihre Methode ihren Vertrag eingehalten hat. Es ist eine Art zu sagen "hier sind die Dinge, von denen erwartet werden kann, dass sie scheitern". Ich würde definitiv MyAppDuplicateExceptionund dergleichen geprüfte Ausnahmen machen (dh nicht RuntimeException s).

Hier gibt es einen sehr guten Artikel , der Ihnen helfen soll, die meisten häufigen Fallstricke zu vermeiden.

Vaughandroid
quelle
Ich sehe Ihren Standpunkt mit Nr. 1. Es ist jedoch meine Erfahrung, dass wir nie auf die Situation stoßen, in der wir alle Arten von Ausnahmen von unseren Diensten abfangen möchten. Wenn etwas schief geht, wollen wir wirklich genau wissen, was es ist. Was ich von Ihnen als zweitem Punkt höre, ist, dass MyAppException RuntimmeException sein sollte. (Die anderen sollten überprüft werden, keine Frage)
Ludwig Magnusson
@vaughandroid, der Link ist kaputt. Hier ist das Archiv: community.oracle.com/docs/DOC-983543
user167569
@ user167569 Danke für das Heads Up. Habe den Link behoben.
Vaughandroid
@LudwigMagnusson # 1 zeigt das Problem, wenn Sie zu einem bestimmten Zeitpunkt einen Zweig von Ausnahmen abfangen möchten , möglicherweise nachdem Sie spezifischere behandelt haben. Das ist nicht dasselbe wie alle Ausnahmen zu fangen . Das Problem mit # 2 ist der Kontext. Sie könnten sagen, dass a IOExceptioneine Laufzeitausnahme für Datei nicht gefunden sein sollte, wenn die Datei eine Ressource ist , die vorhanden sein sollte. Es ist jedoch eine aktivierte Ausnahme für den Fall, dass ein Benutzer einen bestimmten Dateinamen anfordert, der möglicherweise vorhanden ist oder nicht. Dies gilt insbesondere beim Erstellen von Bibliotheken, für die der Kontext nicht im Voraus bekannt ist.
Maarten Bodewes
1

Ich habe erkannt, dass die von unseren Diensten ausgelösten Ausnahmen unsere eigenen anwendungsspezifischen Ausnahmen sein sollten, im Gegensatz zu implementierungsspezifischen Ausnahmen.

Damit meinen Sie Ausnahmen, die durch Ihre Implementierung durch Dritte definiert wurden? Richtig?

Betrachten Sie zunächst eine generische Ausnahme MyAppException. Diese Ausnahme zeigt an, dass etwas Unerwartetes schief gelaufen ist. Das Beste, was wir tun können, ist, dem Benutzer eine Meldung anzuzeigen, dass etwas schief gelaufen ist und wir daran arbeiten. Der Fehler könnte sein, dass die Datenbank abgestürzt ist oder etwas Ähnliches. Diese Ausnahme wird so ziemlich von allen Methoden ausgelöst, die mit der Datenbank arbeiten.

Wenn diese Art von Ausnahme einen Fehler in Ihrem Programm darstellt, der nicht durch schlechte Benutzereingaben, sondern durch ein Problem mit Ihrem Code verursacht wird, sollte es sich in Java um eine Laufzeitausnahme handeln.

Zweitens betrachten Sie eine Ausnahme MyAppDuplicateException. Diese Ausnahme würde anzeigen, dass der Benutzer versucht hat, etwas in der Datenbank zu speichern, das bereits vorhanden war. Hier können wir eine viel spezifischere Fehlermeldung anzeigen, und diese> Ausnahme wird nur von den Methoden ausgelöst, die Datenbankzeilen einfügen oder aktualisieren.

Dies ist eine aktivierte Ausnahme in Java.

Wenn die anderen Ausnahmen MyAppException nicht erweitern, sollte MyAppException> eine java.lang.RuntimeException sein?

Ja.

Dies würde nicht erfordern, Code auszuführen, um ihn abzufangen, was für mich natürlich klingt,> da der Punkt der Ausnahme darin besteht, zu sagen, dass etwas Unbekanntes passiert ist und> nicht erwartet wird, dass der ausführende Code damit umgehen kann. Der Code am> Einstiegspunkt der Anforderung kann weiterhin eine try / catch-Anweisung enthalten, die> MyAppException abfängt und sicherstellt, dass dem Benutzer eine Nachricht angezeigt wird.

Ja, das ist richtig.

user48910
quelle
Du verstehst mich richtig.
Ludwig Magnusson
Wenn Sie sagen, dass der Fehler durch "ein Problem mit meinem Code" verursacht wird, möchte ich nur darauf hinweisen, dass das Problem auch bei der Datenbankverbindung usw. liegen kann. Nicht nur bei Programmierfehlern.
Ludwig Magnusson