如何在exception情况下打印完整的堆栈跟踪?
例如,在一个地方…
//---------------a try { // some network call } catch(WebException we) { throw new MyCustomException("some message ....", we); }
…在另一个地方…
//--------------b try { // invoke code above } catch(MyCustomException we) { Debug.Writeline(we.stacktrace); // <---------------- }
我打印的堆栈跟踪,它只从a开始到b,它不包含WebException中的内部堆栈跟踪。
我怎样才能打印所有的堆栈跟踪?
我通常对exception使用.ToString()方法,以文本方式显示完整的exception信息(包括内部堆栈跟踪):
catch (MyCustomException ex) { Debug.Writeline(ex.ToString()); }
示例输出:
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
使用这样的function:
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(); }
那么你可以这样调用它:
try { // invoke code above } catch(MyCustomException we) { Debug.Writeline(FlattenException(we)); }
如果你将exception传递给下面的函数,它会给你所有的例外的原因和方法。
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(); }