你能在不捕获异常的情况下检查异常吗?

本文关键字:检查 异常 情况下 捕获异常 | 更新日期: 2023-09-27 17:53:55

我有一些框架/AOP代码,记录来自内部调用的方法的异常…

try {
  ..invoke inner code...
}
catch (Exception e) {
  log(e);
  throw;
}

这个工作很好,除了一件事…当我的团队试图在Studio中调试他们的代码时,他们只看到日志代码中发生的异常(因为它被处理,然后从那里抛出)。

是否有任何方法可以让Studio忽略我的代码正在捕获/抛出异常…或者在它通过的过程中检查异常而不捕获它?

更新:问题是我的框架代码阻止了real异常的正确断点被命中。我知道visual studio中的调试器能够进行细粒度配置,我希望这里有人可以提供比"在31小时内学习VS2010"更高层次的见解。我只是想记录在内部代码中引起的异常,并有中断发生在错误的网站没有打开"中断所有异常",这将导致我的团队花5分钟按下"继续"按钮,每次他们启动应用程序(但那是另一个故事)。

更新2:这里的主要问题是,我如何记录异常,但调试器不停止在我的日志记录器中的'throw',但在初始异常,没有调试器停止在所有抛出的异常。

你能在不捕获异常的情况下检查异常吗?

实际上你可以使VS中断异常。转到Debug菜单,单击exceptions并选中"Common Language Runtime exceptions"的两个复选框。现在您将在抛出异常的地方得到一个调试中断

我做了一些调查,1349613的答案给了我一个很好的线索。我添加了属性:

[DebuggerNonUserCode]
到我的日志类。现在,当内部被调用的代码抛出异常时,调试器忽略日志代码,它的Try/Catch块,并直接进入内部异常。

这在VB中是可能的。. NET在不捕获异常的情况下检查异常,并且在因此发生任何堆栈展开之前。虽然在抛出异常和展开堆栈之间做很多事情通常是危险的,但可以捕获异常,然后在finally块中使用它。还可以设置一个标志或其他指示符,让堆栈展开代码知道异常将在哪里被捕获。不幸的是,后一种能力的有用性受到限制,因为(主要是语言强制的)代码捕获异常的反模式需要作出反应,但不能指望解析。例如,如果在构造函数创建了一些IDisposable对象并将它们存储在字段中之后抛出了异常,那么构造函数必须通过清理它创建的字段来对异常做出反应,但是没有希望解决这种情况并正常返回。如果构造函数可以有多个返回点,那么在语义上更简洁的做法是:

try
{
  ... create IDisposables
}
finally(Exception ex)
{
  if (ex != null)
    this.Dispose();
}

而不是说

try
{
  ... create IDisposables
}
catch(Exception ex)
{
  this.Dispose();
  throw ex;
}

,因为前者会避免捕获它不期望处理的异常。可以在VB中编写一个包装器方法,它将接受一对委托,并使用与上面的finally(Exception ex)相同的语义实现第二个委托,但不幸的是c#本身没有提供这样的功能。