Frage

Ich habe mit Fällen befassen, in denen ich werfen würde / rethrow eine Ausnahme zu wissen, dass der Code das es umgibt würde die spezifische Ausnahme fangen. Aber gibt es eine Zeit, die Sie wollen würden, eine Ausnahme zu werfen, dass das Wissen, es wäre nicht gefangen werden?

oder zumindest nicht eine Ausnahme fangen?

Ausnahmen stoppen sofort die Anwendung, es sei denn, ihr Recht behandelt? Also ich denke, ich frage, ob Sie jemals absichtlich wollen würde, lassen Sie Ihre Anwendung sterben?

War es hilfreich?

Lösung

Wenn Ihre Anwendung wird in erster Linie von anderen Clients verwendet werden und ist nicht standalone, macht es im allgemeinen Sinn Ausnahmen auslösen, wenn eine Bedingung auftritt, dass Sie nicht wissen, wie man (oder wollen nicht) handhaben, und es gibt keine vernünftige Möglichkeit für Sie, sich davon zu erholen. Kunden sollten in der Lage zu entscheiden, wie sie alle Ausnahmen zu handhaben wollen, dass Sie vielleicht werfen.

Auf der anderen Seite, wenn Ihre Anwendung ist der Endpunkt, eine Ausnahme zu werfen wird im Wesentlichen ein Benachrichtigungsmechanismus Menschen aufmerksam zu machen, dass etwas schrecklich schiefgelaufen ist. In solchen Fällen müssen Sie ein paar Dinge beachten:

  • Wie wichtig ist das Weiterlaufen der Anwendung? Ist dieser Fehler wirklich nicht behebbar? eine Ausnahme werfen und Ihr Programm endet nicht etwas, was Sie wollen, ist auf dem Space Shuttle zu tun.

  • Sind Sie Ausnahmen als Proxy für echte Protokollierung mit Es gibt so gut wie nie ein Grund, dies zu tun?; sollten Sie stattdessen einen echten Logging-Mechanismus. Fangen Sie die Ausnahme und hat den Logger herausfinden, was passiert ist.

  • Was wollen Sie durch das Werfen der Ausnahme selbst vermitteln? Fragen Sie sich, was der Wert in eine neue Ausnahme zu werfen ist, und sorgfältig prüfen, ob es nicht eine bessere Art und Weise zu tun, was Sie wollen.

  • keine Ausnahme fangen können Ressourcen in einem schlechten Zustand verlassen. Wenn Sie nicht ordnungsgemäß beende, sind die Dinge für Sie in der Regel nicht gereinigt. Stellen Sie sicher, dass Sie verstehen, was Sie tun, wenn Sie brauchen, dies zu tun -. Und wenn Sie es nicht gehen zu fangen, zumindest einen try-finally Block betrachten, so dass Sie einige aufzuräumen tun können,

Andere Tipps

Es gibt eine sehr gute Regel, dass ich auf eine Weile her kam:

eine Ausnahme ausgelöst, wenn eine Methode kann nicht tun, was der Name sagt es tut.

Die Idee ist, dass eine Ausnahme zeigt an, dass etwas schief gegangen ist. Wenn Sie eine Methode implementieren, ist es nicht in Ihrer Verantwortung bewusst zu sein, ob es wird richtig oder nicht verwendet werden. Ob der Code mit Ihrer Methode fängt die Ausnahme oder nicht, ist nicht Ihre Verantwortung, aber in der Verantwortung der Person, die Ihr Verfahrens.

Eine weitere Regel ist:

Verwenden Sie keine Ausnahme fangen, wenn Sie wissen, was Sie damit tun wollen.

Natürlich sollten Sie Bereinigungscode in einem try ... finally-Block, aber man sollte nie nur eine Ausnahme fangen, nur um zu fangen sie gehören. Und Sie sollten nie Ausnahmen leise schlucken. Zwar gibt es Gelegenheiten, wenn Sie alle Ausnahmen wünschen können (indem catch (Exception ex) in C # zum Beispiel) zu fangen, sind diese ziemlich ungewöhnlich und haben in der Regel einen sehr spezifischen technischen Grund. Zum Beispiel, wenn Sie Threads in .NET 2.0 oder höher verwenden, wenn eine Ausnahme von dem Thread entkommt, wird es die gesamte Anwendungsdomäne zu entladen verursachen. In diesen Fällen auf dem Minimum sollten Sie jedoch die Ausnahme Details als ein Fehlerprotokoll und eine Erklärung in den Kommentaren zur Verfügung stellen.

Im Allgemeinen, und sicherlich in frühen Iterationen Ihrer Anwendung, nicht die Ausnahme abfangen. Mehr als oft nicht, sind die Genesung von einer Ausnahme wird eine Geschäftsregel irgendeiner Art benötigen, und mehr als oft nicht, diese Geschäftsregeln nicht für Sie definieren. Wenn Sie die Ausnahme „Griff“ anstatt die Anwendung zu lassen sterben, dann werden Sie höchstwahrscheinlich zu erfinden sein Geschäftsregeln für Ihre Kunden. Nicht gut.

Das allgemeine Muster hat mir mehr Kopfschmerzen verursacht jede Ausnahme, nur um es zu fangen fangen als ich zählen kann. Es geschieht in der Regel, dass jemand eine Art generische Ausnahmebehandlung Code in der gesamten Anwendung bringt, die zwangsläufig landet einen Fehler versteckt oder ein bestimmtes Verhalten zu schaffen, die unerwünscht ist. (Übrigens, fangen und dann nicht Erneutes Auslösen ist noch schlimmer.)

Also, ich würde vorschlagen, dass Sie fragen stattdessen: "Wann soll ich eine Ausnahme zu fangen"

Klar. Zum Beispiel, wenn Sie versuchen, ein paar Bytes in einen String in Java zu laden:

try {
  String myString = new String(byteArray, "UTF-8");
} catch (UnsupportedEncodingException e) {
  // Platform doesn't support UTF-8?  What is this, 1991?
  throw new RuntimeExceptione(e);
}

In diesem Fall gibt es keine Graceful Degradation kann die Plattform einfach nicht unterstützt die gewünschte Operation. Sie können alles, was Sie wollen, bei der Initialisierung für diesen Zustand prüfen, aber der Konstruktor für String wirft noch diese Ausnahme, und Sie müssen damit umgehen. Entweder das, oder verwenden Sie Charset.forName ():)

Hier ist das Ding ... es geht um „Schichten“ oder „Verkapselung“ oder „low-Kopplung“. An einem gewissen Platz in Ihrer Code-Basis, gerade schreiben Sie eine Methode, etwas zu tun. Sagen Sie es eine öffentliche Methode ist. Daher sollte es nicht viel oder etwas über den Anrufer übernehmen ... besser gesagt, es sollte nur die Arbeit machen es tun soll, unabhängig davon, wer sie anruft und was Kontext der Anrufer in.

Und wenn aus irgendeinem Grunde, kann es nicht seine Aufgabe abgeschlossen ist, dann muss es den Anrufer sagen „Sorry, ich kann das nicht tun, und hier ist der Grund“. Ausnahmen sind ein ausgezeichneten Mechanismus zu lassen, um die Anrufer zu sagen, dass (nicht den einzigen Mechanismus, aber der besten Mechanismus ich je für die meisten Fälle gesehen habe).

Wenn Sie also die Ausnahme werfen, haben Sie keine Ahnung, ob es wird ... gefangen werden oder nicht, weil Sie eine öffentliche Methode sind auszusetzen, und Sie haben keine Ahnung, wer könnte es wählen nennen und warum.

Die von der Ausnahme zu kontrollieren, ist die Aufgabe des „Kontextes“. Zum Beispiel, sagen Sie eine Bibliothek mit öffentlichen Methoden schreiben, welche Ausnahme auslösen könnte. Dann sagen Sie, dass die Bibliothek verwenden aus einer Windows-Anwendung Forms. Die Windows Forms app Ausnahmen abfangen könnte und ein Meldungsfeld für den Benutzer anzuzeigen.

Aber später, könnte man die gleiche Bibliothek von Windows-Dienst verwenden. Der Dienst würde eher die Ausnahme zu fangen, es einzuloggen, gibt einen Fehler zurück an den ursprünglichen Anrufer, sondern weiterlaufen, damit es weitere Anfragen verarbeiten.

So ist die Ausnahme, wie eine vertragliche Vereinbarung zwischen dem Anrufer und dem Anbieter. Der Anbieter sagt: „Ich werde entweder den Job oder Ihnen sagen, warum ich nicht kann. Was man von dort tun, um Ihr eigenes Geschäft ist.“ Und der Anrufer sagt: „OK, wenn Sie den Job nicht machen können, nur sagen Sie mir, warum, und ich werde entscheiden, was in diesem Fall zu tun ist.“

  

Aber gibt es eine Zeit, die Sie würde eine Ausnahme werfen wollen, zu wissen, dass es nicht gefangen werden würde?

Ich würde sagen, dass, wenn Sie manuell eine Ausnahme zu werfen sind, die meiste Zeit Sie wissen nicht, ob sie gefangen werden. Wenn Sie es wissen, dass man kann es selbst gefangen wird nur behandeln, anstatt die Ausnahme an erster Stelle zu werfen.

Um fair zu sein, nehme ich an, dass auf der Art der Programmierung hängt teil Sie tun, und manchmal die gleichen Programmierer endet sowohl die Bibliothek den Aufbau und den Code, der Bibliothek sagte verbraucht.

  

Würden Sie jemals nicht eine Ausnahme fangen?

Wenn Sie nicht erwarten, / war nicht bewusst eine Ausnahme ausgelöst werden könnte. Aber das beiseite setzen und vorausgesetzt, Sie kennen die Ausnahme sind, manchmal wissen Sie darüber an einem Tier, aber kennen die nächste Stufe nach oben ist der geeignetere Ort, um es zu behandeln.

Es hängt von der Art der Anwendung. Web-Anwendungen können laufen auch nach Ausnahmen haben den Ausführungskontext sprudelt.

Es ist gängige Praxis zu ‚throw / rethrow‘ eine Ausnahme, wenn Sie die Ausnahme auf einem Niveau zu fangen, wo sie nicht behandelt werden. Aber würden Sie fast immer hinzufügen Zusammenhang mit der Frage, zumindest einige Protokollierung auf der höheren Ebene hinzufügen, zu sagen, dass er gefangen wurde und erneut ausgelöst.

zum Beispiel

A ruft B ruft C (wirft Ausnahme)

B Fänge / rethrows

A Fänge.

In diesem Fall würden Sie B einige Protokollierung hinzufügen, so dass Sie zwischen B Erzeugen und wirft einen Fehler unterscheiden können, und C erzeugt und einen Fehler zu werfen. Das würde ermöglicht es Ihnen, eine größere Fähigkeit, Probleme zu debuggen und zu beheben später.

In der Regel werden Sie fast nie wollen eine Ausnahme Ihr Programm zu töten. Die beste Vorgehensweise ist die Ausnahme zu fangen und anmutig zu verlassen. Auf diese Weise können Sie alle aktuell geöffneten Informationen speichern und freigeben Ressourcen, die verwendet werden, damit sie nicht beschädigt werden. Wenn Sie verlassen möchten, können Sie Ihren eigenen ‚core-Dump‘ Informationen Bericht erstellen, der die Dinge enthält, die Sie tun, als Sie die fatale Ausnahme gefangen.

Wenn Sie lassen die Ausnahme Ihren Prozess töten Sie beseitigen Ihre Chance, maßgeschneiderte Crash-Informationen zu erhalten, und Sie werden das Überspringen auch den Teil, in dem Sie den Benutzer mit einem freundlichen Fehlermeldung liefern und dann beenden.

Also, ich würde empfehlen Ausnahmen immer zu kontrollieren, und nie freiwillig lassen sie Amok in Ihrem Programm.

Bearbeiten

Wenn Sie eine Bibliothek schreiben, müssen Sie vor der Zeit entscheiden, ob Ihre Funktion eine Ausnahme ausgelöst wird, oder eine Ausnahme sicher sein. In diesen Fällen manchmal werden Sie eine Ausnahme und haben keine Ahnung, werfen, wenn die Anrufer es zu fangen. Aber in diesem Fall ist es zu kontrollieren, ist nicht Ihre Verantwortung, solange die api erklärt, dass die Funktion Ausnahmen auslösen könnte. (Ich bin für ein Wort suchen, bedeutet ‚könnte möglicherweise Exception werfen‘ ... Wer weiß, was es ist? Es abzuhören wird mich den ganzen Tag).

Zum einen gibt absolut sind Situationen, in denen es besser ist, nicht eine Ausnahme zu fangen.

Manchmal kann eine Ausnahme manchmal Ihnen sagen, dass Ihr Programm in einem unbekannten Zustand ist. Es gibt eine Reihe von Ausnahmen, bei denen dies der Ausnahmetyp gegeben ziemlich eigen wahr ist. Ein NullReferenceException im wesentlichen aussagt, „gibt es einen Fehler“. Und durch eine solche Ausnahme zu kontrollieren, können Sie den Fehler verbergen, die auf kurze Sicht gut klingt, aber auf lange Sicht würden Sie glücklicher sein, um es zu beheben. Das Produkt kann nicht abstürzen, aber es wird sicherlich nicht das erwartete Verhalten haben.

Aber das gilt auch für die Ausnahmetypen, die wir für uns selbst erfinden. Manchmal ist die Tatsache, dass Ausnahme A geworfen werden sollte „unmöglich“ sein -. Und doch ist es geschehen, so gibt es einen Bug

Auch etwas sehr Wichtiges passiert, wenn Sie eine Ausnahme zu fangen: die finally Blöcke für den gesamten Call-Stack innerhalb des Try-Blockes (und alles, was es nennt) ausgeführt. Was tun diese schließlich Blöcke? Nun, alles. Und wenn das Programm in einem unbekannten Zustand ist, dass ich wirklich meinen alles . Sie konnten wertvolle Kundendaten von der Festplatte löschen. Sie konnten mehr Ausnahmen werfen. Sie könnten korrupte Daten im Speicher, so dass der Fehler nicht zu diagnostizieren.

So

, wenn eine Ausnahme einen unbekannten Zustand anzeigt, Sie wollen nicht mehr Code auszuführen, so was auch immer Sie tun, nicht fangen die Ausnahme . Lassen Sie es vorbei fliegen, und das Programm wird beendet überbrückt und Windows-Fehlerberichterstattung in der Lage, den Zustand des Programms zu erfassen, wie es war, als das Problem ursprünglich festgestellt wurde. Wenn Sie die Ausnahme abfangen, werden Sie mehr Code verursachen auszuführen, was den Zustand des Programms wird vermasseln.

Zweitens sollten Sie eine Ausnahme aus, zu wissen, es wird nicht gefangen werden? Ich denke, diese Frage die Art von wieder verwendbaren Methoden mißversteht. Die ganze Idee eines Verfahrens ist, dass es einen „Vertrag“ hat, dass es folgt: es bestimmte Parameter akzeptiert und gibt einen bestimmten Wert, und auch wirft es bestimmte Ausnahmen unter bestimmten Bedingungen. Das ist der Auftrag - es ist bis zu dem Anrufer, was sie damit machen. Für einige Anrufer könnte Ausnahme A einen behebbaren Zustand anzuzeigen. Für andere Anrufer, könnte es einen Fehler hinweisen. Und von dem, was ich oben gesagt, sollte es klar sein, dass, wenn eine Ausnahme einen Fehler anzeigt, es darf nicht gefangen werden .

Und wenn Sie sich fragen, was dies für die Microsoft Enterprise Library Exception Hantierungsbausteins : ja, es ist ziemlich kaputt. Sie sagen Ihnen, catch (Exception x) und dann entscheiden, ob auf der Grundlage Ihrer Politik erneut auslösen; zu spät - die finally Blöcke wurden bereits von diesem Punkt ausgeführt. Tu das nicht.

Sie würden wahrscheinlich nicht eine abgefangene Ausnahme überall wollen, wo die Endnutzer können es sehen, aber es ist oft akzeptabel Kunden Ihrer API (andere Programmierer) entscheiden zu lassen, wie Ausnahmen zu behandeln.

Zum Beispiel: Angenommen, Sie eine Java-Klassenbibliothek entwerfen. Sie entlarven eine öffentliche Methode, die in einem String nimmt. In Ihrer Anwendung würde ein Null-Eingangswert einen Fehler verursachen. Statt den Fehler selbst zu handhaben, wäre es akzeptabel, für einen Nullwert zu überprüfen, dann eine Illegal werfen.

Sie müssen natürlich, Dokument, das Ihre Methode, um diese Ausnahme in diesem Umstand wirft. Dieses Verhalten wird zu einem Teil Ihrer Methode Vertrag.

Es hängt davon ab, was Sie unter ‚gefangen‘. Etwas, irgendwo schließlich fängt die Ausnahme, ob sie das zugrunde liegende Betriebssystem oder etwas anderes sein.

Wir haben ein Workflow-System, die Job-Pläne aus einzelnen Jobs ausführt. Jeder Job läuft eine Einheit von Code. Für einige der Ausnahmen, wir wollen sie nicht in dem Code zu handhaben, aber es, den Stapel zu werfen, so dass das externe Workflow-System fängt sie (die vollständig außerhalb des Verfahrens der Werfer passieren).

Wenn Sie die gesamte Anwendung schreiben, dann sind Ihre Gründe, Ihre eigenen. Ich kann von ein paar Situationen denken, wo Sie könnte wollen die Ausnahme werfen und lassen Sie die App sterben, die meisten von ihnen sind nicht sehr gute Gründe, though.

Der beste Grund, in der Regel ist beim Debuggen. Ich häufig Ausnahmen deaktivieren, während das Debuggen mir zu erlauben, besser zu wissen, wo etwas versagt. Sie können auch auf ausgelöste Ausnahme bricht im Debugger drehen nur, wenn Sie es auf einer Maschine mit dem Debugger ausführen.

Ein weiterer möglicher Grund ist, wenn weiterhin nach eine Ausnahme ausgelöst wird nicht sinnvoll oder möglich unwiederbringlichen Datenkorruption oder schlechter (man denke Roboter mit Laserstrahlen zur Folge haben würde, aber dann sollten Sie verdammt sicher sein, Ihre applicaiton beschäftigt sich mit diesen Situationen IMO , das Programm abstürzt ist nur die faule Art und Weise).

Wenn Sie API-Code schreiben, oder Framework-Code, den Sie selbst nicht verwenden, dann haben Sie keine Ahnung, ob jemand Ihre Ausnahmen fangen wird.

Yup, es ist meine einzige Möglichkeit, den Entwickler zu schlagen den Dienst / Objekt raubend, ihnen zu sagen „Ur dO1n es falsch !!!!“.

Das und immer Möglichkeiten befreien, die Sie nicht wollen, ermöglichen oder scheinbar „unmöglich“ sind. Apps, die alle Ausnahmen und weiterhin ist nur ummauerten Garten von Chaos umgeben fangen.

Wenn ich brauche ein mäßig großes System, das irgendwie Datenverarbeitung ist in dem, was ich glaube, eine konsistente Art und Weise zu sein.

und

Irgendwo entlang der Linie, erkenne ich, dass der Staat die Anwendung geworden ist inkonsistent.

und

Das System funktioniert (noch) nicht wissen, wie die Inkonsistenz zu beheben und erholt anmutig

Dann ja, würde ich eine Ausnahme mit so detailliert wie möglich werfen und die Anwendung verursachen, so schnell wie möglich zu sterben, tun jeden weiteren Schaden an den Daten zu vermeiden. Wenn es zurückgewonnen werden kann, wäre es wichtig zu sein, nicht um das Problem zu verschärfen, indem schwächlich versuchen, das Chaos zu verschleiern.

Später entlang der Linie, sobald die Kette der Ereignisse, die zur Inkonsistenz geführt wird besser verstanden, ich höhere Anlage kann diese Ausnahme abfangen, reparieren den Zustand, und weiterhin mit minimaler Unterbrechung.

Eine Bibliothek oft Ausnahmen werfen basierend auf defensiver Programmierung überprüft werden soll entsteht eine Bedingung, dass nicht erlaubt wurde, durch den Anwendungscode zu ergeben. Applikationen-Code wird oft so geschrieben werden, dass die meisten dieser ungültigen Bedingungen niemals entstehen, und deshalb werden die Ausnahmen nie geworfen werden, so gibt es keinen Grund, sie zu kontrollieren.

auf die Sprache Je (Ich bin meist in Form von C ++ statt C # zu denken, und nicht so klar, was die Unterschiede sind) die Wirkung einer abgefangene Ausnahme tatsächlich geworfen wird, ist wahrscheinlich das gleiche wie das, was verwendet in der getan werden Tage vor Ausnahmen wurden erfunden. Eine gemeinsame Politik für defensive Programmierung in C-Bibliotheken, zum Beispiel, war das Programm sofort mit einer Fehlermeldung zu beenden.

Der Unterschied besteht darin, dass, wenn die Ausnahme throw möglich sein, tut sich herausstellen (hoffentlich wird dies durch Unit-Tests entdeckt werden), ist es oft relativ einfach ist, eine Exception-Handler hinzuzufügen, die von dem Problem in einer konstruktiven Art und Weise zu erholen. Sie müssen die Bibliothek nicht neu schreiben, oder komplexe Kontrollen im Anwendungscode in dem die Bedingung sicherzustellen, kann nicht entstehen, bevor die Ausnahme Werfen Anruf getätigt wird.

Ich habe schon einige Ausnahme auslöst, die nie gefangen werden. Sie sind alle für defensive Zwecke und während abgefangene ist eine Ausnahme schlecht ist, was passieren tut, geschieht dies immer nur während der Entwicklung und Prüfung auf Fehlerbedingungen ich nicht so weit in den Anwendungscode zu prüfen. Und wenn es passiert, ist es ungewöhnlich, dass die fix umständlich zu sein - keine Notwendigkeit für ein groß angelegtes Refactoring, keine Notwendigkeit für die Code-Anwendungen massiv mit Fehlerzustand überprüft kompliziert, nur eine catch-Klausel mit einer relativ einfachen Wiederherstellung oder " Es tut mir leid, Dave, ich fürchte, ich kann das nicht tun.“ ohne die gesamte App andernfalls aus.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top