In einem kürzlich durchgeführten Projekt habe ich empfohlen, eine RuntimeException in einem Test-Harness-Code abzufangen und zu protokollieren. Der Code verarbeitet eine Reihe von Eingaben aus einer Datenbank, und ich möchte nicht, dass der Test aufgrund eines Fehlers einer Eingabe (Nullwerte, unzulässige Argumente usw.) gestoppt wird. Unnötig zu erwähnen, dass mein Vorschlag eine leidenschaftliche Diskussion auslöste.
Ist es akzeptabel, irgendeine Art von RuntimeException zu fangen? Wenn ja, in welchen anderen Szenarien ist es in Ordnung, RuntimeExceptions abzufangen?
quelle
Wenn Sie eine RuntimeException nicht korrigieren können, möchten Sie sie nicht abfangen ...
... nur aus Entwicklersicht wahr ....
Sie müssen alle Ausnahmen abfangen, bevor sie die Benutzeroberfläche erreichen und Ihren Benutzer traurig machen . Dies bedeutet, dass Sie auf der "höchsten Ebene" alles fangen möchten, was weiter unten passiert ist. Dann können Sie den Benutzer über ein Problem informieren und gleichzeitig Maßnahmen ergreifen, um die Entwickler zu informieren, z. B. das Versenden von Alarm-Mails oder was auch immer ...
Grundsätzlich handelt es sich um einen Daten- / Programmierfehler, der nicht vorhergesehen werden konnte. Sie möchten daher zukünftige Versionen der Software verbessern und gleichzeitig den Benutzer bei der Hand nehmen und kontrolliert weitermachen ...
quelle
RuntimeException soll für Programmiererfehler verwendet werden. Als solches sollte es niemals gefangen werden. Es gibt einige Fälle, in denen es sein sollte:
Sie rufen Code von einem Drittanbieter auf, bei dem Sie keine Kontrolle darüber haben, wann dieser eine Ausnahme auslöst. Ich würde argumentieren, dass Sie dies von Fall zu Fall tun und die Verwendung des Codes von Drittanbietern in Ihre eigenen Klassen einschließen sollten, damit Sie Nicht-Laufzeit-Ausnahmen zurückgeben können.
Ihr Programm kann nicht abstürzen und dem Benutzer eine Stapelverfolgung hinterlassen. In diesem Fall sollte es sich um Haupt- und um Threads und Ereignisbehandlungscode handeln. Das Programm sollte wahrscheinlich beendet werden, wenn eine solche Ausnahme ebenfalls auftritt.
In Ihrem speziellen Fall müsste ich mich fragen, warum in den Tests RuntimeExceptions auftreten - Sie sollten sie beheben, anstatt sie zu umgehen.
Sie sollten also sicherstellen, dass Ihr Code nur dann RuntimeExceptions auslöst, wenn Sie das Programm beenden möchten. Sie sollten RuntimeExceptions nur abfangen, wenn Sie es protokollieren und beenden möchten. Dies steht im Einklang mit der Absicht von RuntimeExceptions.
Sie können sich diese Diskussion aus anderen Gründen ansehen , die die Leute angeben ... Ich persönlich habe jedoch keinen zwingenden Grund in den Antworten gefunden.
quelle
Vor Jahren haben wir ein Steuerungssystem-Framework geschrieben, und die Agent-Objekte haben Laufzeitausnahmen abgefangen, sie protokolliert, wenn sie konnten, und wurden fortgesetzt.
Ja, wir haben Laufzeitausnahmen einschließlich OutOfMemory in unserem Framework-Code abgefangen (und einen GC erzwungen, und es ist überraschend, wie gut das auch ziemlich undichten Code ausgeführt hat.) Wir hatten Code, der sehr mathematische Dinge in der realen Welt ausführte. und von Zeit zu Zeit kam eine Not-A-Nummer aufgrund winziger Rundungsfehler herein und es kam auch damit klar.
Also im Framework / "darf nicht beenden" Code denke ich, dass es gerechtfertigt sein kann. Und wenn es funktioniert, ist es ziemlich cool.
Der Code war ziemlich solide, aber es lief Hardware, und Hardware neigt manchmal dazu, verrückte Antworten zu geben.
Es wurde entwickelt, um monatelang ohne menschliches Eingreifen zu laufen. In unseren Tests hat es sehr gut funktioniert.
Als Teil des Fehlerbehebungscodes kann das gesamte Gebäude neu gestartet werden, indem die USV in N Minuten ausgeschaltet und in M Minuten eingeschaltet werden kann.
Manchmal müssen Hardwarefehler aus- und wieder eingeschaltet werden :)
Wenn ich mich recht erinnere, war der letzte Ausweg nach einem erfolglosen Aus- und Einschalten das Senden einer E-Mail an die Eigentümer mit der Aufschrift "Ich habe versucht, mich selbst zu reparieren und ich kann nicht; das Problem liegt im Subsystem XYZ" und einem Link zum Aufrufen eines Supports Rufen Sie uns zurück.
Leider wurde das Projekt eingemacht, bevor es sich selbst bewusst werden konnte :)>
quelle
In meinem Code werden 99% meiner Ausnahmen von runtime_exception abgeleitet.
Die Gründe, warum ich Ausnahmen fange, sind:
Zum Beispiel ein HTTP-Request-Handler. Ich würde lieber die angeforderte Operation sterben lassen, als den Service herunterzufahren. (Obwohl der Handler vorzugsweise genug Sinn hat, um einen 500-Fehlercode zurückzugeben.)
Das Zulassen, dass Ausnahmen einem Thread entkommen, ist normalerweise schlecht dokumentiert, führt jedoch normalerweise zum Beenden des Programms (ohne Abwickeln des Stapels).
quelle
Persönlich wurde mir immer gesagt, dass Sie alle RuntimeExceptions abfangen möchten. Sie möchten jedoch auch etwas gegen die Ausnahme unternehmen , z. B. eine Ausfallsicherheit ausführen oder den Benutzer möglicherweise nur über das Auftreten eines Fehlers informieren.
Das letzte Java-Projekt, an dem ich gearbeitet habe, hatte einen ähnlichen Ansatz. Zumindest haben wir die Ausnahme protokolliert, damit wir, wenn ein Benutzer anruft und sich über einen Fehler beschwert, genau herausfinden können, was passiert ist, und sehen können, wo der Fehler aufgetreten ist.
Edit 1: Wie kdgregory sagte, sind Fangen und Ignorieren zwei verschiedene Dinge, im Allgemeinen sind die Leute gegen Letzteres :-)
quelle
Wir alle wissen, dass geprüfte Ausnahmen und
RuntimeExceptions
sind die beiden Kategorien von Ausnahmen. Es wird immer empfohlen, die aktivierten Ausnahmen zu behandeln (entweder zu versuchen oder zu werfen), da dies die Programmierbedingungen sind, unter denen der Programmierer leider nichts alleine tun kann. AlsFileNotFoundException
ob es nicht der Programmierer ist, der Dateien auf das Laufwerk des Benutzers legt, wenn das Programm tatsächlich versucht, die Datei zu lesen, die1.txt
auf demf:\
Benutzer mit den folgenden Anweisungen vorhanden sein soll:File f11 = new File("f:\\1.txt"); FileInputStream fos = new FileInputStream(f11);
Wenn die Datei gefunden wird, ist alles in Ordnung, aber im anderen Fall, wenn die Datei nicht gefunden wird, stürzt das Programm mit dem Fehler 0 des Benutzers ab. In diesem Szenario hat der Programmierer nichts falsch gemacht. Dies kann eine aktivierte Ausnahme sein, die abgefangen werden muss, damit das Programm weiter ausgeführt werden kann.
Lassen Sie mich auch das zweite Szenario erklären, mit dem das Konzept von
RuntimeException
klar wird. Betrachten Sie folgenden Code:int a = {1,2,3,4,5}; System.out.println(a[9]);
Dies ist eine schlechte Codierung, die die erzeugt
ArrayIndexOutOfBoundsException
. Welches ist ein Beispiel fürRuntimeException
. Daher sollte der Programmierer die Ausnahme nicht wirklich behandeln, das Programm abstürzen lassen und später die Logik korrigieren.quelle
Sie fangen,
RuntimeException
wenn Sie es verarbeiten möchten. Vielleicht möchten Sie es als eine andere Ausnahme erneut auslösen oder in einer Datei oder Datenbank protokollieren, oder Sie möchten ein Ausnahmeflag im Rückgabetyp usw. aktivieren.quelle
Sie fangen RuntimeExceptions ab (in jeder Sprache: unerwartete Ausnahmen / "alle" Ausnahmen), wenn Ihr Programm mehrere Unteraufgaben ausführt, und es ist sinnvoll, alle möglichen Aufgaben abzuschließen, anstatt bei der ersten unerwarteten Situation anzuhalten. Eine Testsuite ist eine gute Situation, um dies zu tun - Sie möchten wissen, welche von allen , nicht nur der erste Test nicht bestanden die Tests. Das Hauptmerkmal ist, dass jeder Test unabhängig von allen anderen ist - es spielt keine Rolle, ob ein vorheriger Test nicht ausgeführt wird, da die Reihenfolge ohnehin nicht von Bedeutung ist.
Eine andere häufige Situation ist ein Server; Sie möchten nicht herunterfahren, nur weil eine Anforderung auf eine Weise fehlerhaft war, die Sie nicht erwartet hatten. (Es sei denn, es ist wirklich sehr wichtig, die Wahrscheinlichkeit eines inkonsistenten Zustands zu minimieren.)
In jeder dieser Situationen ist es angemessen, die Ausnahme zu protokollieren / zu melden und mit den verbleibenden Aufgaben fortzufahren.
Man könnte vage auf jede Ausnahme verallgemeinern: Es ist „angemessen“, eine Ausnahme genau dann abzufangen, wenn nach dem Abfangen etwas Sinnvolles zu tun ist: wie Ihr Programm fortgesetzt werden soll .
quelle
Wenn von einem Client vernünftigerweise erwartet werden kann, dass er sich von einer Ausnahme erholt, machen Sie ihn zu einer aktivierten Ausnahme.
Wenn ein Client nichts tun kann, um die Ausnahme wiederherzustellen, machen Sie es zu einer nicht aktivierten Ausnahme.
Hier ist die Grundlinie.
Aus Java Docs . Bitte lesen Sie diese ungeprüften Ausnahmen - Die Kontroverse
quelle