9 Stimmen

Wie implementiert man die Behandlung von Ausnahmen auf höchster Ebene?

Vor kurzem musste ich ein zusätzliches Modul für einen bestehenden Dienst entwickeln, der von einem Kollegen entwickelt wurde. Er hatte einen Try/Catch-Block in die Hauptarbeitsfunktion eingefügt, um alle unbehandelten Ausnahmen abzufangen, die bis zu dieser Ebene auftraten, und sie zusammen mit Stack-Trace-Informationen usw. zu protokollieren:

try
{
    // do main work
}
catch(Exception ex)
{
    // log exception info
}

Das macht das Programm zwar sehr stabil (im Sinne von "unwahrscheinlich, dass es abstürzt"), aber ich hasse es, weil ich beim Testen meines Codes die dadurch verursachten Ausnahmen nicht sehe. Natürlich kann ich in das Ausnahmeprotokoll schauen und sehen, ob es neue Einträge gibt, aber ich bevorzuge das direkte Feedback, wenn ich die Ausnahme in dem Moment bekomme, in dem sie ausgelöst wird (mit dem Cursor auf der richtigen Zeile im Code, bitte).

Ich habe diese oberste Ebene try/catch entfernt, zumindest solange ich noch kodiert und getestet habe. Aber jetzt ist meine Aufgabe beendet und ich muss entscheiden, ob ich es für die Veröffentlichung wieder einfüge oder nicht. Ich denke, dass ich es tun sollte, weil es den Dienst stabiler macht, und der ganze Sinn des Dienstes ist, dass er im Hintergrund läuft, ohne dass man ihn überwachen muss. Andererseits habe ich gelesen, dass man nur bestimmte Ausnahmen aufrufen sollte (wie in IoException ), nicht allgemein Exception .

Was raten Sie zu diesem Thema?

Übrigens ist das Projekt in C# geschrieben, aber ich bin auch an Antworten für andere Sprachen als .NET interessiert.

12voto

OscarRyz Punkte 189898

Legen Sie es zurück.

Die Ausnahme sollte nur beim Testen relevant sein. Ansonsten macht es keinen Sinn, sie dem Benutzer anzuzeigen.

Die Protokollierung ist in Ordnung.

Sie können zusätzlich das von Visual Studio definierte DEBUG-Symbol für Debug-Builds als Flag verwenden.

    ...
    } catch( Exception e ) { 
#if DEBUG
          throw;
#else
          log as usual 
#endif
    }

Wenn also das nächste Mal eine Änderung erforderlich ist, sollte das Debug-Flag auf true gesetzt werden, und die Ausnahme wird angezeigt.

4voto

Eddie Punkte 52504

In jeder Java-Anwendung sollten Sie fast immer einen Exception-Handler für nicht abgefangene Ausnahmen definieren, etwa so:

Thread.setDefaultUncaughtExceptionHandler( ... );

wo das Objekt, das diese nicht abgefangenen Ausnahmen auffängt, zumindest den Fehler protokolliert, so dass Sie eine Chance haben, davon zu erfahren. Andernfalls gibt es keine Garantie, dass Sie überhaupt benachrichtigt werden, dass ein Thread eine Exception ausgelöst hat - es sei denn, es ist Ihr Hauptthread.

Zusätzlich zu tun dies, die meisten meiner Threads haben ein Try/Catch, wo ich fangen wird RunnableException (aber nicht Error ) und protokollieren es ... einige Threads sterben, wenn dies geschieht, andere protokollieren und ignorieren es, wieder andere zeigen dem Benutzer eine Beschwerde an und lassen ihn entscheiden, je nach den Bedürfnissen der Anwendung. Dieses try/catch befindet sich an der Wurzel des Threads, in der Runnable.run() oder eine gleichwertige Methode. Da die try/catch-Methode an der Wurzel des Threads liegt, ist es nicht notwendig, diese Catch-Methode manchmal zu deaktivieren.

Wenn ich in C# schreibe, kodiere ich auf ähnliche Weise. Aber das hängt alles von den Anforderungen der Anwendung ab. Ist die Exception eine, die Daten beschädigen wird? Dann fangen Sie sie nicht ab und ignorieren Sie sie. Protokollieren Sie sie IMMER, aber lassen Sie die Anwendung dann sterben. Die meisten Ausnahmen sind jedoch nicht von dieser Art.

2voto

Kenneth Cochran Punkte 11762

Im Idealfall möchten Sie eine Ausnahme so nah wie möglich an dem Ort behandeln, an dem sie aufgetreten ist, aber das bedeutet nicht, dass ein globaler Exception-Handler eine schlechte Idee ist. Vor allem bei einem Dienst, der um jeden Preis weiterlaufen muss. Ich würde mit dem fortfahren, was Sie bisher getan haben. Deaktivieren Sie ihn während der Fehlersuche, aber lassen Sie ihn für die Produktion bestehen.

Denken Sie daran, dass es als Sicherheitsnetz verwendet werden sollte. Versuchen Sie dennoch, alle Ausnahmen zu erfassen, bevor sie so weit gehen.

2voto

Mohit Chakraborty Punkte 1251

Der Drang, alle Ausnahmen abzufangen und das Programm "stabil" zu machen, ist sehr stark, und die Idee scheint in der Tat für alle sehr verlockend. Das Problem, auf das Sie hinweisen, ist, dass dies nur ein Trick ist und das Programm sehr wohl fehlerhaft und schlimmer sein kann, ohne dass es Hinweise auf Fehler gibt. Niemand überwacht die Protokolle regelmäßig.
Mein Rat wäre, zu versuchen, den anderen Entwickler davon zu überzeugen, ausführliche Tests durchzuführen und sie dann ohne den äußeren Haken in der Produktion einzusetzen.

1voto

Chris Woodruff Punkte 551

Wenn Sie die Ausnahme sehen wollen, wenn sie auftritt, können Sie in Visual Studio das Menü DEBUG aufrufen, AUSNAHMEN auswählen und dem Debugger sagen, dass er abbrechen soll, sobald eine Ausnahme ausgelöst wird. Sie können sogar die Art der Ausnahmen auswählen :)

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