(0) exportieren Drucken
Alle erweitern
Erweitern Minimieren

MSDN Chat - Fehlerbehandlung in .NET Programmen

Veröffentlicht: 01. Sep 2003 | Aktualisiert: 11. Nov 2004
Von Jörg Neumann und Neno Loje

Wir möchten Sie darauf aufmerksam machen, dass es sich in diesem Transkript nicht um die exakten Zitate der Teilnehmer handelt. Wir haben die Kommentare im Rahmen der besseren Verständlichkeit angepasst.

* * *

Auf dieser Seite

Problemstellung: Beim Abfangen einer Exception, die in einem WebService auftritt, kommt immer eine SoapException an. Problemstellung: Beim Abfangen einer Exception, die in einem WebService auftritt, kommt immer eine SoapException an.
Problemstellung: In einem Programm sollen alle Exceptions, die nicht explizit mit try-catch gefangen wurde, behandelt werden. Problemstellung: In einem Programm sollen alle Exceptions, die nicht explizit mit try-catch gefangen wurde, behandelt werden.
Problemstellung: Stack zum Zeitpunkt einer Exception auswerten Problemstellung: Stack zum Zeitpunkt einer Exception auswerten
Problemstellung: Exceptions über .NET Remoting verschicken Problemstellung: Exceptions über .NET Remoting verschicken
Problemstellung: Wie soll eine Funktion einen Fehler zurückgeben. Problemstellung: Wie soll eine Funktion einen Fehler zurückgeben.
Problemstellung: Unbehandelte Fehler unter ASP.NET abfangen Problemstellung: Unbehandelte Fehler unter ASP.NET abfangen

Problemstellung: Beim Abfangen einer Exception, die in einem WebService auftritt, kommt immer eine SoapException an.


Frauke : Wenn ich einen WebService schreibe und der Server wirft einen Fehler, dann bekomme ich im Client immer eine SoapException. Das finde ich nicht gut. Ich möchte da auch meine "echte" Exception sehen.

NenoL: Wenn Du in einem WebService eine Exception werfen willst, kannst Du diverse Konstruktorüberladungen von SoapException verwenden. Dort kann man dann zum Beispiel eine eigene Fehlermeldung, einen Fehlercode oder eine serialisierbare Exception übergeben. Dies geht sogar so weit, dass man die Möglichkeit hat, eine beliebige Anzahl von XML-Nodes zu übergeben. Diese kann dann per SOAP übertragen und clientseitig verarbeitet werden. Dazu findest Du detaillierte Informationen auf: http://www.learnxmlws.com/book/chapter6/.

Frauke : Das heißt ich muss meine eigene Exception von SoapException ableiten?

NenoL: Du kannst Deine Exceptions weiterhin z.B. von System.ApplicationException ableiten. Solange diese serialisierbar sind kannst Du Sie beim throw new SoapException(...) reinreichen. Falls Du keine eigene Exception wirfst oder Deine Exception nicht in eine SoapException verpackst, kommt die Originalfehlermeldung als Message-Eigenschaft mit der SoapException mit.

Frauke : Also sollte ich in WebServices immer eine SoapException ausdrücklich selbst werfen? Klingt sogar ein wenig plausibel :-)

NenoL: Genau. Die Exception, die Du im Konstruktor reinreichst, kannst Du beim Client aus der InnerException-Eigenschaft der SoapException ziehen.

Problemstellung: In einem Programm sollen alle Exceptions, die nicht explizit mit try-catch gefangen wurde, behandelt werden.


Laci22 : Um ein absturzsicheres Programm zu erstellen, sollte jeder Ereignisfunktion ein try-catch Block beinhalten?

NenoL: Du hast die Möglichkeit einen anwendungsweiten "globalen" Errorhandler zu erstellen, der alle Exceptions abfängt, die nicht in einem try-catch-Block auftreten.

Der Code, der alle unbehandelten Exceptions abfängt muss folgende Signatur haben:

using System.Threading; 
public static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 
{ 
  //TODO: Hier Logik zum Behandeln von Exceptions implementieren. 
}

Diesen Handler musst Du in Deiner Main()-Methode folgendermaßen anmelden bevor Du Application.Run() aufrufst:

Application.ThreadException += new  
ThreadExceptionEventHandler(ErrorHandler.Application_ThreadException);

Problemstellung: Stack zum Zeitpunkt einer Exception auswerten


Frauke : Wenn ich eine Exception fange, kann ich dann den Stack zum Zeitpunkt der Ausnahme durchlaufen und feststellen, wie die Parameter bis dahin ausgesehen haben?

JoergN: Die Exception-Klasse hat eine StackTrace-Eigenschaft. Die zeigt Dir in Stringform den Programmverlauf. Alternativ kannst Du auch ein neues System.Diagnostic.StackTrace-Objekt erstellen und ihm im Konstruktor die Exception übergeben. Mit diesem Objekt ist dann ein Durchlaufen der einzelnen Stack Frames möglich.

[Nachträgliche Ergänzung: Im Folgenden Beispiel wird ein StackTrace auf Grundlage einer Exception erstellt und der Methodenname inkl. Parameter und Zusatzinformationen des ersten Stack Frames ausgegeben.]

// StackTrace aus Exception erstellen 
StackTrace trace = new StackTrace(ex, true); 
// StackFrame aus StackTrace ermitteln 
StackFrame frame = trace.GetFrame(0); 
// Klassen- und Funktionsnamen aus StackFrame ermitteln 
MethodBase method = frame.GetMethod(); 
string traceString = "Fehler in " + 
 method.DeclaringType + "."; 
 method.Name + "("; 
// Methoden-Parameter ermitteln 
ParameterInfo[] paramInfos = method.GetParameters(); 
string methodParams = ""; 
foreach (ParameterInfo paramInfo in paramInfos) 
{ 
 methodParams += ", " + paramInfo.ParameterType.Name + " " + paramInfo.Name; 
} 
if (methodParams.Length > 2) 
 traceString += methodParams.Substring(2); 
// Zeile, Spalte, ILOffset und Datei ermitteln 
traceString +=  
 ") in Zeile " + frame.GetFileLineNumber().ToString() +  
 ", Spalte " + frame.GetFileColumnNumber().ToString() +  
 ", ILOffset: " + frame.GetILOffset() +  
 ", Datei: \"" + frame.GetFileName() + "\"" +  
 Environment.NewLine; 
// Fehlerzeile ausgeben 
Console.WriteLine(traceString);

Problemstellung: Exceptions über .NET Remoting verschicken


ClaudiaK : Wie kann ich ein Exception-Object über Remoting verschicken?

JoergN: Das ist kein Problem, solange die Exception serialisierbar ist. Das heißt die Exception-Klasse muss mit dem Serializable-Attribut ausgestattet sein oder das ISerializable-Interface implementieren.

Problemstellung: Wie soll eine Funktion einen Fehler zurückgeben.


ClaudiaK : Was ist denn nun besser, für einen Fehler false aus einer Funktion zurückzugeben oder eine Exception zu werfen?

NenoL: Wenn es eine zu erwartende Fehlersituation ist, wie zum Beispiel dass der Benutzer einen Dialog abbricht, dann solltest Du Rückgabewerte (wie false oder null) verwenden. Im Falle einer Ausnahme, also einem unerwarteten Ereignis, beispielsweise wenn nicht genügend Speicher vorhanden ist, ist eine Exception das Richtige.

ClaudiaK : Aber wenn ich in meinen Code einen Exceptionhandler einbaue, dann erwarte ich doch schon eine Situation.

JoergN: Der Vorteil des Exception-Handlings ist, dass genauere Informationen über den Fehler bereitgestellt werden.

ClaudiaK : Du meinst, eine Exception mit meinen Properties sagt mehr, als ein simples false oder ein Enum-Wert? Aber eine Exception hat doch auch immer einen anderen Programmfluss zur Folge.

JoergN: Genau. Eine Exception bietet mehr Informationen über den Fehler und den Programmverlauf.

ClaudiaK : Ja, aber wenn ich mal ein false zurückliefere und mal eine Exception, dann muss ich einmal mit if reagieren und einmal mit try-catch. das ist eben so anderes.

JoergN: Deshalb solltest Du Dich möglichst für eine Variante entscheiden.

Problemstellung: Unbehandelte Fehler unter ASP.NET abfangen


Frauke : Unterscheidet sich das Exception-Handling bei ASP.NET eigentlich von dem in WinForms Applikationen?

NenoL: Um alle unbehandelten Fehler in einer ASP.NET Anwendung zu behandeln, musst Du in der global.aspx das Ereignis "Error" abfangen. Dort kannst Du mittels Server.GetLastError() an die Exception kommen. Allerdings wird die Exception immer in eine HttpUnhandledException verpackt, sodass Du die InnerException auslesen musst um an die relevanten Informationen zu kommen.


Anzeigen:
© 2014 Microsoft