Welches Fehlerbehandlungsmodell ist robuster?

8

Ich bin irgendwie zwischen diesen beiden Fehlerbehandlungsmodellen hin- und hergerissen:

  1. Erstellen Sie eine boolesche Error und eine Zeichenfolge ErrorMessage -Eigenschaft für Ihr Objekt. Fangen Sie alle Exceptions intern in den Methoden des Objekts ab und übergeben Sie die Nachrichten mit bedingter Logik vom Aufrufer, zB:

    %Vor%
  2. Wirf Ausnahmen in dein Objekt und handle sie auf der Außenseite mit Try Catch logic:

    %Vor%

Für mich sieht es nach der gleichen Menge Code aus, außer dass Sie Eigenschaftscode für die Eigenschaften Error und ErrorMessage haben. Sie können jedoch auch erkennen, wenn ein Fehler auftritt, ohne nach Ausnahmen suchen zu müssen. Mit welchem ​​Muster sollte ich gehen?

    
Jason 13.09.2009, 18:39
quelle

6 Antworten

1

Ich empfehle beide.

Warum?

"Verwenden Sie das richtige Werkzeug für den Job"

Das "Problem" mit Rückkehrcodes ist, dass Leute oft vergessen, mit ihnen umzugehen. Ausnahmen lösen dieses Problem jedoch nicht! Die Leute behandeln immer noch keine Ausnahmen (sie wissen nicht, dass eine bestimmte Ausnahme behandelt werden muss, sie gehen davon aus, dass jemand auf dem Stapel damit klarkommt oder sie verwenden eine catch () und quetschen alle Fehler).

Während ein unbehandelter Rückgabecode möglicherweise bedeutet, dass sich der Code in einem instabilen Zustand befindet, garantiert eine unbehandelte Ausnahme oft , dass das Programm abstürzt. Ist das besser?

Obwohl ein Rückgabecode beim Schreiben von Code leicht zu identifizieren ist, ist es oft unmöglich (oder einfach nur mühsam) festzustellen, welche Ausnahmen von einer aufgerufenen Methode ausgelöst werden. Dies führt normalerweise zu einer sehr schlechten Ausnahmebehandlung.

Ausnahmen sollen für "Fehler" verwendet werden. Darin liegt die Schwierigkeit. Wenn eine Datei nicht gefunden wird, wenn Sie versuchen, sie zu öffnen, ist das ein "Fehler" oder eine "erwartete Situation"? Nur der Anrufer weiß es. Durch die Verwendung von Exceptions wird jede Statusinformation im Wesentlichen zu einem Fehler.

Letztendlich ist die Fehlerbehandlung etwas, an dem ein Programmierer arbeiten muss. Dieses Problem besteht sowohl in Rückkehrcodes als auch in Ausnahmen.

Daher verwende ich Rückkehrcodes für die Weitergabe von Statusinformationen (einschließlich "Warnungen") und Ausnahmen für "schwerwiegende Fehler". (Und ja, manchmal ist es schwer zu beurteilen, in welche Kategorie etwas fällt)

Beispielfall von .net:

Int32.Parse löst Ausnahmen aus (auch wenn keine der Ausnahmen Fehler sind - der Aufrufer muss die Ergebnisse überprüfen und selbst entscheiden, ob das Ergebnis gültig ist). Und es ist einfach ein Schmerz (und ein Leistungseinbruch), dass man jeden Aufruf in einem Versuch / Fangen einschließen muss. Und wenn Sie vergessen, einen Versuch / Fang zu verwenden, kann ein einfaches leeres Texteingabefeld Ihr Programm zum Absturz bringen.

Somit wurde Int32.TryParse () geboren. Das macht das Gleiche, gibt aber statt einer Ausnahme einen Fehlercode zurück, so dass Sie Fehler einfach ignorieren können (für ungültige Eingaben wird der Standardwert 0 akzeptiert). In vielen realen Situationen ist dies viel sauberer, schneller, einfacher und sicherer zu verwenden als Int32.Parse ().

"TryParse" verwendet eine Namenskonvention, um dem Aufrufer klar zu machen, dass Fehler auftreten können, die korrekt behandelt werden sollten. Ein anderer Ansatz (um Programmierer zu erzwingen, Fehler besser zu behandeln) besteht darin, den Rückgabecode in einen out- oder ref-Parameter umzuwandeln, so dass der Aufrufer explizit auf die Notwendigkeit hingewiesen wird, zurückgegebene Fehler zu behandeln.

    
Jason Williams 13.09.2009, 20:35
quelle
7

Ich habe beschlossen, Ausnahmen auszuwerfen, anstatt Fehler- / Rückgabecodes zu verwenden. Ich habe gerade erst wirklich intensiv nachgedacht.

Der Grund, warum Ausnahmen ausgelöst werden, ist die Möglichkeit, dass Sie vergessen, den Fehlercode zu überprüfen. Wenn Sie es nicht überprüfen, werden Sie weiterarbeiten, während der Fehler besteht. Mit Ausnahmen, wenn Sie vergessen, sie zu behandeln, wird die Ausnahme an die Spitze und stoppen Sie alle Verarbeitung. Es ist besser, dass dies geschieht, als nach dem Auftreten unbekannter Fehler fortzufahren.

Weitere Informationen finden Sie im Kapitel "Ausnahmen" in Framework-Design-Richtlinien: Konventionen, Idiome und Muster für wiederverwendbare. NET-Bibliotheken, zweite Ausgabe von Addison-Wesley.

Joel Spolsky bevorzugt eigentlich Fehler / Rückgabe-Codes über Ausnahmen, aber viele Leute stimmen ihm nicht zu. Joels Post zugunsten von Rückkehrcodes kann hier gefunden werden. Schauen Sie sich diesen Blogbeitrag und alle Kommentare mit einer guten Diskussion zu diesem Thema an.

    
Dennis 13.09.2009 18:50
quelle
3

Bevorzugen Sie # 2. Weitere Informationen finden Sie in diesem Auszug zum Exception Throwing aus der Entwicklung von Microsofts Excellent < a href="http://rads.stackoverflow.com/amzn/click/0321545613"> Framework Design Richtlinien , wie Dennis erwähnt. Beachten Sie insbesondere den Abschnitt zu Ausnahmen und Leistung.

Kurze Version:

  

Geben Sie keine Fehlercodes zurück.

     

Melden Sie Ausführungsfehler, indem Sie Ausnahmen auslösen.

     

Verwenden Sie keine Ausnahmen für den normalen Kontrollfluss.

Ich empfehle dringend, das Buch für eine vollständige Diskussion zu lesen, einschließlich Kommentaren von einigen der Microsoft-Koryphäen.

    
TrueWill 13.09.2009 18:54
quelle
3

Ausnahmen sollten verwendet werden, wenn etwas außergewöhnlich passiert ist.

z.B. Sie erhalten ein Null (Nichts) -Objekt, wenn Sie eines erwarten.

Onkel Bob empfiehlt Ausnahmen für Fehlercodes in seinem Buch Clean code .

Er sagt

  

Das Problem mit diesen [Fehlercodes] -Ansätzen ist, dass sie den Anrufer durcheinander bringen. Der Anrufer muss unmittelbar nach dem Anruf auf Fehler prüfen. Leider ist es leicht zu vergessen. Aus diesem Grund ist es besser, eine Ausnahme auszulösen, wenn ein Fehler auftritt. Der aufrufende Code ist sauberer. Seine Logik wird durch die Fehlerbehandlung nicht verdeckt.

    
Johnno Nolan 13.09.2009 18:59
quelle
2

Das größte Problem, das ich mit dem ersten Problem habe, ist, dass es passiv ist, leicht übersehen wird und nicht sehr standardisiert ist. Wie kann ein Programmierer diese Eigenschaft überprüfen? Oder welche Eigenschaften / Methoden können einen Fehler verursachen? Oder welcher Eigenschaft / Methoden-Zugriff hat den Fehler verursacht?

Zum Beispiel. Wenn in Ihrem ersten Beispielcode o.Error True ist, ist es unklar, ob die Initialisierung des Objekts oder der Aufruf von SomeMethod das Setzen des Flags verursacht hat.

Das Ausnahmemodell ist eine nicht zu ignorierende Möglichkeit, Ihren Benutzern mitzuteilen, dass ein Fehler aufgetreten ist. Es kann nicht ohne expliziten Code vermieden werden, um mit der Situation umzugehen.

    
JaredPar 13.09.2009 18:43
quelle
2

Sie sind beide akzeptierte Formen der Fehlerbehandlung, aber die bevorzugte Wahl für .NET-Sprachen ist die Verwendung von Ausnahmen.

Es gibt einige Probleme bei der Verwendung von Rückgabecodes (entweder numerisch oder boolesch), die beiden größten sind:

  • Von Programmierern leicht übersehen / ignoriert.
  • Kann nicht in allen Situationen verwendet werden. Was passiert, wenn der Konstruktor fehlschlägt? Es ist nicht möglich, einen Wert explizit von einem Konstruktor zurückzugeben.

Aus diesen Gründen sollten Sie Ausnahmen verwenden. Ausnahmen bieten eine saubere, standardisierte Möglichkeit, Fehler anzuzeigen, unabhängig davon, wo sie auftreten.

Sie werden auch insgesamt weniger Code haben, da Sie nur Ausnahmen abfangen sollten, wenn und wo Sie diese Ausnahme sicher und angemessen behandeln können.

    
Scott Dorman 13.09.2009 19:01
quelle

Tags und Links