确定哪一行代码抛出了异常

6
在dotNet中,一行代码抛出异常并被捕获后,我该如何确定是哪个文件的哪一行抛出的异常?这似乎很简单,但我无法弄清楚...
4个回答

6

只有在有调试符号的情况下才能执行此操作。

catch(Exception ex) {
    // check the ex.StackTrace property
}

如果您想在VS中调试这种情况,最好只需在“Debug”菜单中的“Exceptions”对话框中勾选“Common Language Runtime Exceptions”的“Thrown”复选框即可。即使异常在try块中,调试器也会在抛出异常时立即中断。


2

就我个人而言,我只记录异常的ToString()返回值。整个堆栈跟踪都包括在内。这只需要一行代码...非常简单。


1
你可以使用StackFrame类
try
{
    ...
    ...

}
catch(...)
{
    StackFrame sf = new StackFrame(true);

    int lineNumber = sf.GetFileLineNumber();
    int colNumber = sf.GetFileColumnNumber();
    string fileName = sf.GetFileName();
    string methodName = sf.GetMethod().Name;
}

4
请注意,这将返回“catch”子句的信息...而不是异常抛出的位置,如果需要检查捕获的异常的“StackTrace”属性内容! - jerryjvl
这个答案是错误的,正如jerryjvl所说的那样。怎么能把它作为正确的答案接受呢? - Timwi

1
在.NET中,你有所谓的FirstChanceException。这些异常基本上是在异常被处理之前抛出的。您可以从两个角度考虑您在此处展示的问题。一个是从调试角度看待。如果正在进行调试,您可以将调试器设置为从“Debug/Exceptions”窗口捕获抛出的异常。这在交互式环境中更容易。如果您需要从非交互式环境记录此信息,则我会执行与CMS类似的操作...
try
{
    ...
}
catch(Exception ex)
{
    System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(ex);
    System.Diagnostics.StackFrame firstFrame = stackTrace.GetFrame[0];
    Console.WriteLine(firstFrame.GetFileLineNumber);
    ...
}

这里唯一的区别是我们获取整个堆栈跟踪,然后转到第一个帧,也就是最初引发异常的地方。

帧0不是当前方法的帧,而是错误发生的位置吗? - Mike Rosenblum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接