3 Stimmen

Behandlung von Ausnahmen - was passiert nach dem Verlassen von catch

Stellen Sie sich also vor, Sie haben eine Ausnahme, die Sie abfangen, und in der Abfangphase schreiben Sie dann in eine Protokolldatei, dass eine Ausnahme aufgetreten ist. Dann wollen Sie, dass Ihr Programm weiterläuft, also müssen Sie sicherstellen, dass bestimmte Invarianten noch in einem guten Zustand sind. Aber was passiert eigentlich im System, nachdem die Ausnahme durch einen Catch "behandelt" wurde?

Der Stapel wurde zu diesem Zeitpunkt abgewickelt, wie kann er also seinen Zustand wiederherstellen?

6voto

sbi Punkte 211669

"Stack unwinding" bedeutet, dass alle Scopes zwischen throw und die dazugehörige catch Klausel verlassen, die Destruktoren für alle automatischen Objekte in diesen Bereichen aufruft, ziemlich genau so, wie Funktionsbereiche verlassen werden, wenn man aus einer Funktion zurückkehrt.

Es wird nichts weiter "Besonderes" getan, der Umfang einer catch Klausel ist ein normaler Geltungsbereich, und sein Verlassen unterscheidet sich nicht vom Verlassen des Geltungsbereichs einer else Klausel.

Wenn Sie sicherstellen müssen, dass bestimmte Invarianten weiterhin gelten, müssen Sie den Code, der sie ändert, thread-sicher programmieren. Dave Abrahams schrieb _ein Klassiker über die verschiedenen Ebenen der Ausnahmesicherheit_ sollten Sie das vielleicht lesen. Grundsätzlich müssen Sie konsequent einsetzen RAII um beim Auftreten von Ausnahmen auf der sicheren Seite zu sein.

2voto

Péter Török Punkte 111735

Es liegt an Ihnen, dafür zu sorgen, dass die Anwendung nach dem Abfangen der Ausnahme wieder in einen stabilen Zustand gebracht wird. In der Regel wird dies dadurch erreicht, dass die Operation oder Änderung(en), die die Ausnahme verursacht haben, "vergessen" werden und auf einer höheren Ebene neu begonnen wird.

Dazu gehört auch, dass alle Ressourcen, die während der Ereigniskette, die zur Ausnahme führt, zugewiesen wurden, ordnungsgemäß freigegeben werden. In C++ ist das Standardidiom, um dies zu gewährleisten RAII .

Update

Wenn beispielsweise bei der Verarbeitung einer Anfrage in einem Webserver ein Fehler auftritt, wird in einer Funktion auf niedrigerer Ebene eine Ausnahme erzeugt, die in einer Klasse auf höherer Ebene abgefangen wird (möglicherweise direkt im Top Level Request Handler). In der Regel ist es am besten, alle vorgenommenen Änderungen rückgängig zu machen und alle Ressourcen freizugeben, die bisher im Zusammenhang mit der eigentlichen Anfrage zugewiesen wurden, und eine entsprechende Fehlermeldung an den Client zurückzugeben. Zu den Änderungen können DB-Transaktionen, Dateischreibvorgänge usw. gehören - all dies muss auf ausnahmesichere Weise implementiert werden. Datenbanken verfügen in der Regel über eingebaute Transaktionen, um dies zu bewältigen; bei anderen Ressourcen kann es schwieriger sein.

2voto

sharptooth Punkte 162790

Nur Objekte, die innerhalb der try beim Abwickeln zerstört werden. Es liegt an Ihnen, ein Programm so zu schreiben, dass beim Auftreten einer Ausnahme der Programmzustand konsistent bleibt - das nennt man Ausnahme Sicherheit .

C++ kümmert sich nicht darum - es wickelt den Stapel ab und übergibt dann die Kontrolle an eine geeignete catch , dann wird der Kontrollfluss normal fortgesetzt.

1voto

xtofl Punkte 39285

Dies ist eine Frage der Anwendung. Es gibt mehrere Ebenen der Ausnahmesicherheit. Das von Ihnen beschriebene Niveau ist für die gesamte Anwendung schwer zu erreichen.

Bestimmte Teile des Codes können jedoch durch den Einsatz von Techniken wie RAII und durch eine geschickte Anordnung der Abfolge von Aktionen "fehlertransparent" gemacht werden. Ich könnte mir z.B. ein Stück Code vorstellen, das mehrere URLs nach Daten abfragt: Wenn eine URL "abbricht", können die restlichen URLs immer noch verarbeitet werden. Oder es kann erneut versucht werden...

0voto

AndersK Punkte 34870

Wenn Sie in jeder Funktion eine Ausnahmebehandlung haben, können Sie auf der nächsthöheren Ebene fortfahren, aber das ist ziemlich kompliziert. Ich verwende Ausnahmen hauptsächlich, um Fehler so nah wie möglich an der Quelle zu erkennen, aber nicht, um die Ausführung fortzusetzen.

Wenn es andererseits Fehler gibt, die vorhersehbar sind, kann man Schemata entwickeln, um damit umzugehen, aber für mich werden Ausnahmen als Ausnahmen betrachtet, so dass ich dazu neige, stattdessen zu versuchen, das Programm elegant zu beenden, mit einem guten Hinweis in der Protokolldatei, wo es passiert ist. JM2CW

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X