Warum sollte ich alle Anweisungen in Try-Catch schreiben?


12

Mein Firmenchef sagt, dass ich alles schreiben muss, dh ALLEN Code in Try-Catch-Anweisungen. Jetzt kann ich verstehen, dass hier die Vorgehensweise "Sicher ist sicher" besser ist, aber ist es nicht zu klug zu glauben, dass es bei der Erstellung der Beschriftungen zu einer Ausnahme kommt, wenn die Position des Formulars festgelegt wird? Gab es Fälle, in denen Ausnahmen bei solchen einfachen Operationen vorkamen?


4
Dies klingt wie Schlagworte von denselben Leuten, die sagen, dass alle SQL-Anweisungen als gespeicherte Prozeduren geschrieben werden sollten, um eine bessere Leistung zu erzielen.
Spong

5
Würden Sie bevorzugen: "Wenn Ihr Code einen Laufzeitfehler erzeugt, werden Sie gefeuert." Das Spiel mit dem Huhn macht Spaß, bis Sie sehen, wie Ihr Gegner das Lenkrad und das Bremspedal aus dem Fenster wirft.
JeffO

4
@ Jeff O - Ich glaube tatsächlich, dass der Gegner in der Softwareentwicklung ein Güterzug ist.
Joris Timmermans

5
Der beste Ausdruck, den ich für diese Art der Ausnahmebehandlung gehört habe, ist "Den Leichnam in die aufrechte Position nageln", was bedeutet, dass die Anwendung in einem unerwarteten Zustand bleibt. Fail Fast, Fail Loudly ist ein viel moderner Ansatz, mit dem Sie alle Fehler beheben können.
Brook

2
Das Thema der Anfrage ist irrelevant ... nur zu sagen, "mein Firmenchef sagt, ich solle codieren ..." ist eine große rote Fahne. Es ist Mikromanagement ... das ist nicht seine Aufgabe.
JoelFan

Antworten:


14

Mein Firmenchef sagt, dass ich alles schreiben muss, dh ALLEN Code innerhalb von Try-Catch-Anweisungen.

Nun, das ist etwas übertrieben und führt nur zu verrauschtem Code. Was sind die Vorteile, wenn der gesamte Code (z. B. jede Methode) mit einem Try-Catch-Handler geschrieben wird? In den meisten Fällen muss ein Fehler behoben werden. Oft kann und sollte die Ausnahme überhaupt vermieden werden.

Ein Blick auf den Stack-Trace reicht meistens aus, um die Ursache in Ihrem Code aufzudecken, auch wenn die fehlerhafte Methode den Catch selbst nicht ausführt. Es gibt Zeiten, in denen Entwickler Stack-Traces in Ausnahmebedingungen beschädigen. Dies ist jedoch weitaus häufiger der Fall, wenn Sie über zahlreiche Ausnahmebehandlungsroutinen verfügen. Wie alles: Ein bisschen ist gut, aber zu viel davon ist Gift.

Die Ausnahmebehandlung ist in der Tat ziemlich einfach:

Fang Ausnahmen

  • Wann immer Sie eine spezielle Aktion als Reaktion auf die Ausnahme benötigen
  • wenn eine Ausnahme das Programm in einem inkonsistenten Zustand belässt, wenn sie nicht behandelt wird

Wenn Sie darüber nachdenken, gibt es meistens nur einen Ort, an dem eine auftretende Ausnahme behandelt werden kann. Und so sollte der Handler an diesem Ort sein.

Viele Ausnahmen sollten gar nicht erst ausgelöst werden. Bauen Sie Ihre Kontrollstrukturen also nicht auf die Ausnahmebehandlung auf, sondern vermeiden Sie das mögliche Auftreten von Ausnahmen, wann immer und wo immer dies möglich ist.

Denken Sie daran, frühzeitig zu stürzen, wenn (unwiederbringliche) Probleme auftreten. Das Einfügen des gesamten Codes in try-catch-Anweisungen ist absurd. Vergessen Sie jedoch nicht, ALLE Ausnahmen zu melden und zu protokollieren.


+1 Dies führt nicht nur zu verrauschtem Code, sondern auch zu einer noch schlechteren Leistung. Wenn Sie Anweisungen in einen try-Block einfügen, kann der HotSpot-Compiler keine Optimierungen anwenden, die er sonst ausführen würde.
Oliver Weiler

@Oliver Weiler: Haben Sie ein Zitat, das erklärt, welche Optimierungen der HotSpot-Compiler in Try / Catch-Blöcken nicht vornimmt?
Kaypro II

16

Aber ist es nicht zu klug zu glauben, dass es eine Ausnahme geben wird, wenn die Beschriftungen erstellt werden, wenn die Position des Formulars festgelegt wird? Gab es Fälle, in denen Ausnahmen bei solchen einfachen Operationen vorkamen?

Absolut ja! Es gibt immer eine Möglichkeit, dass Dinge schief gehen, die Sie nicht vorausgesehen haben. Und "Hühnerherz" ist in diesem Zusammenhang ein lächerlicher Ausdruck. Bei der Softwareentwicklung geht es nicht darum, Ihren Machismo zu beweisen, indem Sie potenzielle Probleme ignorieren.

Was ist eine berechtigte Frage ist , ob es nützlich für Ausnahmen an dem Punkt , wo Ihre Coding - Standards sie haben sagen gefangen werden. Ihre Aussage lautet, dass Sie Try / Catch-Block um jeden Methodenkörper haben müssen, und das ist in der Tat absurd, weil Sie mit einer Ausnahme oft nicht sofort etwas Nützliches tun können, und genau das ist der springende Punkt bei Ausnahmen: Sie können sie zulassen Verteilen Sie den Call-Stack, der an der entsprechenden Stelle behandelt werden soll.


13
Meine Apps wissen es besser, als Ausnahmen zu werfen, sonst werden sie den Sieg ihres Lebens davontragen. Sobald sie denken, dass Sie ein Hühnerherz haben, stürzen sie über Sie hinweg.
JeffO

@Michael Borgwardt: hehe, also hast du mich runtergestimmt. Sie haben diese Frage abgelehnt, und die einzige Ablehnung betrifft meinen Beitrag. Sie scheinen ein ernstes Problem mit Ihrem Ego oder Ihrem Selbstwertgefühl zu haben. Das ist mir auch bei anderen Fragen aufgefallen. Wissen Sie, auch andere Programmierer haben gute Antworten.
Falcon

@ Falcon: Ich habe nichts zu dieser Frage abgelehnt. Ich habe keine Ahnung, was Sie dazu bringt, etwas anderes zu glauben, aber wenn jemand ein ernstes Ego-Problem hat, sind Sie es.
Michael Borgwardt

@Michael Borwardt: Vielleicht irre ich mich. In diesem Fall entschuldige ich mich. Es könnte sein, dass dies nur die Ablehnung Ihrer eigenen Frage ist, die mich zu der Annahme veranlasst hat, dass Sie hier eine Ablehnung vorgenommen haben. Es tut uns leid.
Falcon

8

Ich würde das anders herum machen. Ja, in der Regel ist die Ausnahmebehandlung eine gute Sache, aber können Sie tatsächlich jede mögliche Ausnahme an der Stelle, an der sie abgefangen wird, auf vernünftige Weise behandeln? Manchmal, besonders wenn Sie nicht missionskritische Software schreiben, es ist besser, einfach abstürzen und brennen in einigen halbwegs gesteuert , wenn die Dinge schief gehen.

Wenn Sie nicht hundertprozentig sicher sein können, dass Sie mit jeder einzelnen Ausnahme, die möglicherweise abgefangen wird, fertig sind, ist es wahrscheinlich besser, eine allgemeine Ausnahmebehandlungsroutine zu schreiben, in der die Hauptschleife des Programms eingeschlossen ist - die genaue Vorgehensweise ist offensichtlich Dies hängt davon ab, in welcher Sprache Sie arbeiten. Melden Sie sich dort so detailliert wie möglich über die Ausnahmebedingung an, und speichern Sie den Programmstatus (an einem anderen Ort als in dem Datenspeicher, an dem der Benutzer gerade arbeitet). Beachten Sie, dass an dieser Stelle möglicherweise alle Daten beschädigt sind ), und so weiter. Werfen Sie dann die Ausnahme erneut aus und lassen Sie das Betriebssystem damit umgehen, wie es passt. Seien Sie in diesem Catch-All-Ausnahmehandler auf einen katastrophalen Ausfall vorbereitet. Überprüfen Sie dann nach dem Neustart des Programms, ob dieser Status in irgendeiner Weise nützlich ist, und stellen Sie wieder her, was wiederhergestellt werden kann, wenn dies der Fall ist. und möglicherweise dem Benutzer anbieten, einen Fehlerbericht an Sie zurückzusenden.


5
+1: Fange niemals eine Ausnahme ab, wenn du nicht sofort richtig damit umgehen kannst. (Leider muss man es manchmal abfangen, nur um es wieder frei laufen zu lassen, aber als Teil der API-Zwangsmaßnahmen als ein anderer Typ markiert: Ich hasse das.)
Donal Fellows

6

Insgesamt ist die Verwendung von try / catch so viel veraltet, weil catch-Block vom Standpunkt der Ressourcen so teuer ist. Die Verwendung von Try / Catch erinnert mich an das Risikomanagement . Risikomanagement hat zwei Dimensionen:

  1. Die Wahrscheinlichkeit des Eintretens von Risiken
  2. Der Schaden, den es haben kann

Wenn Sie jetzt das Haus verlassen, ist es so unwahrscheinlich, dass Ihnen ein Klavier auf den Kopf fällt (vielleicht 0,001%), dass Sie jedoch getötet werden können.

Die Ausnahmebehandlung ist so. Try Block ist nicht teuer. Aber catch-Block ist sehr teuer, da eine Tabelle mit Stack-Trace erstellt und andere Aufgaben ausgeführt werden müssen. Daher sollten Sie bei der Entscheidung über try / catch-Blöcke berücksichtigen, wie oft Sie wahrscheinlich catch block treffen. Wenn Sie unter 10.000 Verwendungen nur 1 Mal getroffen haben, verwenden Sie diese. Wenn es sich jedoch um ein Formular handelt und der Benutzer es wahrscheinlich nicht zu 50% korrekt ausfüllt, sollten Sie es vermeiden, dort einen Try / Catch-Block in Aktion zu setzen.

An Orten, an denen die Wahrscheinlichkeit des Auftretens von Ausnahmen hoch ist, wird empfohlen, if {} else {}Blöcke zu verwenden, um das Auftreten von Ausnahmen zu vermeiden. Zum Beispiel, wenn Sie zwei Zahlen teilen möchten, anstatt zu schreiben:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

du solltest schreiben:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}

2
+1 für die Verwendung von if / else zur Behandlung von "Ausnahmen", die im Grunde nur Anwendungslogik sind.
Morgan Herlocker

Denken Sie daran, dass Computer in Bezug auf Benutzer erheblich schneller sind als Menschen. Eine Ausnahme, die in 50% der Formularübermittlungen ausgelöst wird, tritt selbst bei vielen Benutzern wahrscheinlich nur einige Male pro Sekunde auf.
Donal Fellows

1
Ich bin mit Ihnen nicht einverstanden, dass Try / Catch-Blöcke vermieden werden. Das ständige Antizipieren von Ausnahmen ist fehleranfällig, teuer für Entwickler und erschwert das Lesen Ihres Codes. Eine Schleife, die eine Million Ausnahmen auslöst und sie abfängt, benötigt 500 ms, um auf meinem Computer ausgeführt zu werden (gegenüber 1 ms für eine leere Schleife), was in 99,99% der Fälle (und bei allen UI-Codes) kein realer Leistungsunterschied ist. Sie sollten Ausnahmen verwenden, außer in Fällen, in denen Sie wissen, dass die Leistungsminderung von Bedeutung ist, da sie Ihren Code zuverlässiger machen und Sie davon ausgehen lassen, dass der vorherige Code erfolgreich ausgeführt wurde.
Kaypro II

@ cosmic.osmo, holst du dir den Stacktrace oder fängst du ihn einfach?

3

Sie sollten Try-Catch verwenden, wenn dies angebracht ist, aber bitte, bitte fangen Sie nicht alle Ausnahmen ab und protokollieren Sie sie nicht einmal. An diesem Punkt ist es Code Geruch und schlampige Arbeit.


1
+1 für die Protokollierung. Programme in freier Wildbahn sind Black Boxes. Wenn sie versagen, ist ein Protokoll mit der Aufschrift "Hier ist was passiert" ein sehr langer Weg, um das Problem zu lösen. Ich hatte Fehler in meinen Programmen, die nicht gemeldet wurden, und sie wurden erst aufgedeckt, nachdem ich sie im Protokoll gefunden hatte.
Andrew Neely

2

Ich persönlich kann keine Ausnahmen ertragen, sie sind SEHR, SEHR, SEHR schwer richtig zu handhaben. Der Versuch, die korrupten Daten zu löschen, ist SEHR, SEHR, SEHR schwer!

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html

Wenn Sie nicht jede Funktion wie folgt aufrufen:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

Es gibt keine Möglichkeit, an jedem Austrittspunkt richtig aufzuräumen. Ausnahmen sind hart!

Das einzig Gute an Ausnahmen ist, dass die App bei unerwartetem Verhalten abstürzt, wenn Sie sie nicht abfangen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.