2010-11-24 7 views
70

Zum Beispiel an einem Ort ...Wie wird die vollständige Stapelverfolgung in Ausnahmefällen gedruckt?

//---------------a 
try 
{ 
    // some network call 
} 
catch(WebException we) 
{ 
    throw new MyCustomException("some message ....", we); 
} 

... und an einem anderen Ort ...

//--------------b 
try 
{ 
    // invoke code above 
} 
catch(MyCustomException we) 
{ 
    Debug.Writeline(we.stacktrace); // <---------------- 
} 

Die Stacktrace Ich drucke es nur von A nach B starten, es enthält den inneren Stacktrace von der WebException nicht.

Wie kann ich alle Stacktrace drucken ???

+0

Beachten Sie, dass das Stacktrace für die ursprüngliche WebException nicht gedruckt werden würde, da Sie eine neue Ausnahme ausgelöst haben, anstatt die WebException erneut zu werfen. Verwenden Sie 'throw;' anstelle von 'throw new MyCustomException (...)', wenn Sie den ursprünglichen Exception-Stack beibehalten (und ausgeben) möchten. – Beel

Antwort

121

ich in der Regel die .ToString() -Methode auf Ausnahmen verwenden, um die vollständige Ausnahme Informationen zu präsentieren (einschließlich der inneren Stapelüberwachung) in Text:

catch (MyCustomException ex) 
{ 
    Debug.Writeline(ex.ToString()); 
} 

Beispielausgabe:

ConsoleApplication1.MyCustomException: some message .... ---> System.Exception: Oh noes! 
    at ConsoleApplication1.SomeObject.OtherMethod() in C:\ConsoleApplication1\SomeObject.cs:line 24 
    at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 14 
    --- End of inner exception stack trace --- 
    at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 18 
    at ConsoleApplication1.Program.DoSomething() in C:\ConsoleApplication1\Program.cs:line 23 
    at ConsoleApplication1.Program.Main(String[] args) in C:\ConsoleApplication1\Program.cs:line 13 
+0

Sehr gut. Ich war auf der Suche nach einem einfachen Weg, und hier ist es. Ein wenig Bedenken ist, dass es nicht so explizit ist, als ob Sie das stackTrace-Objekt (zum Beispiel) verwenden. Ich frage mich, ob es einen expliziteren Weg gibt, dasselbe zu tun? – codea

+3

Beachten Sie, dass einige Bibliotheken die 'ToString'-Methode überschreiben und benutzerdefinierte Nachrichten anstelle der vollständigen Informationen drucken (dies ist eine schlechte Programmierpraxis, also ** tu das ** nie) – Dinei

42

eine Funktion wie folgt verwenden:

public static string FlattenException(Exception exception) 
    { 
     var stringBuilder = new StringBuilder(); 

     while (exception != null) 
     { 
      stringBuilder.AppendLine(exception.Message); 
      stringBuilder.AppendLine(exception.StackTrace); 

      exception = exception.InnerException; 
     } 

     return stringBuilder.ToString(); 
    } 

Dann können Sie es so nennen:

try 
{ 
    // invoke code above 
} 
catch(MyCustomException we) 
{ 
    Debug.Writeline(FlattenException(we)); 
} 
+0

+1, aber Sie könnten einfach AppendLine stattdessen verwenden –

+10

Oder Sie können ToString verwenden? – Justin

+0

Ich benutze den ToString und denke, es ist in Ordnung. Ich würde mit Andrews Lösung gehen, wenn ich nur die niedrigste innere Ausnahme (mit dem tatsächlichen Grund) oder ähnliche Kommissionierung will .. funktioniert beide aber :) – EeKay

5

Wenn Sie Ihre Ausnahme an die folgende Funktion übergeben, erhalten Sie alle Methoden und Details, die die Ursache der Ausnahme sind.

public string GetAllFootprints(Exception x) 
{ 
     var st = new StackTrace(x, true); 
     var frames = st.GetFrames(); 
     var traceString = new StringBuilder(); 

     foreach (var frame in frames) 
     { 
      if (frame.GetFileLineNumber() < 1) 
       continue; 

      traceString.Append("File: " + frame.GetFileName()); 
      traceString.Append(", Method:" + frame.GetMethod().Name); 
      traceString.Append(", LineNumber: " + frame.GetFileLineNumber()); 
      traceString.Append(" --> "); 
     } 

     return traceString.ToString(); 
} 
+0

Ziemlich hilfreich. Ich habe eine [Erweiterungsmethode] (https://github.com/VeaceslavWD/EasySharp/blob/master/NHelpers/CustomExtensionMethods/ExceptionHelper.cs) basierend auf Ihrem Beispiel gemacht. Übrigens sollten Sie im Falle einer großen Anzahl von Iterationen besser die 'StringBuilder' Klasse verwenden. –

Verwandte Themen