【发布时间】:2021-08-03 18:51:03
【问题描述】:
正如我现在已经知道的那样,为了保留原来的 stackTrace,我们应该避免使用 throw 捕获异常,相反,我们应该只使用 throw clause 实际上 @987654325 @异常。
问题是在几天前的一次采访中,我得到了一个代码来预测最终结果的stacktrace:
class Program
{
static void Main(string[] args)
{
try
{
ReThrowException(); // line 17
}
catch (Exception x)
{
Console.WriteLine("Exception:");
Console.WriteLine(x.StackTrace); //line 22
}
}
private static void ReThrowException()
{
try
{
DivByZero();
}
catch
{
throw; //line 34
}
}
private static void DivByZero()
{
int x = 0;
int y = 1 / x; //line 41
}
}
异常发生在 line 41 和第 34 行,它只是 rethrow 异常,保留原来的 stackTrace。
我的回答是:
它实际上应该指向
line 41where 异常 第一次发生且无处stackTrace被覆盖 代码。
但真正的答案如下:
Exception:
at TestConsole.Program.DivByZero() in C:...\Projects\TestConsole\TestConsole\Program.cs:line 41
at TestConsole.Program.ReThrowException() in C:...\Projects\TestConsole\TestConsole\Program.cs:line 34
at TestConsole.Program.Main(String[] args) in C:...\Projects\TestConsole\TestConsole\Program.cs:line 17
现在我想到了两个问题:
1.为什么stackTrace 为行17,34 添加源?
2.我应该在代码中做些什么来让stackTrace指向line 41并删除其他来源?
【问题讨论】:
-
它没有显示“其他来源”。这是一个 stack 跟踪:它显示了引发异常时的调用堆栈。可能有很多地方调用了
DivByZero,堆栈跟踪显示了确切调用它的方法,以及调用那个方法的方法,等等,一直到应用程序的入口点(或线程处理程序,如果它是在后台线程等)。上面写着“Main 在第 17 行调用了 ReThrowException;ReThrowException 在第 34 行调用了 DivByZero(除了它到达了 'throw' 点,而不是原始方法调用);DivByZero 在第 41 行遇到了问题”。 -
你是对的,但是当它指向第 34 行时,似乎我使用的是 throw ex 而不是 throw 子句。
-
没有。如果您使用了
throw ex;,您将丢失指向DivByZero中第41 行的堆栈跟踪部分。throw ex;会彻底清除目前为止记录的堆栈跟踪,重新开始 -
是的,在这种情况下我失去了原件,但它表现得就像我在第 34 行抛出异常。
-
不,不是——你读错了。查看第一个条目以查看引发异常的位置。其余条目显示您的异常“命中”的代码点,直到它最终被捕获并打印。堆栈跟踪没有显示代码中引发异常的所有点:它显示了异常在您的代码中冒泡时通过的所有点。
标签: c# try-catch stack-trace throw