何时检查内部异常



何时检查Exception类及其导数的InnerException性质?Microsoft的"异常最佳实践"没有提供任何关于何时检查内部异常的建议。我应该只在代码中重新抛出并捕获异常时才这样做吗?我应该一直这样做,即使我try-catch块标准函数(如System.IO.File.Move(封装?

谁可能会使用这样的功能?

有时,开发人员会将一个异常(通常由 Microsoft 定义的异常(转换为另一个异常(通常是自己定义的异常(。

这可以使 API 更简单,例如,如您在File.Move()中给出的示例。与 7 个可能的Microsoft异常不同,这样的 API 可以抛出一个简单的"那不起作用"异常,其中包含详细信息,因此您的代码只需要处理一种类型的异常。

什么时候使用它?

在使用第三方框架时,我会在开发阶段研究它们。如果它们倾向于为空,则为其编写代码就没有价值。

如果您编写记录器/跟踪器或通用调试输出,我肯定会考虑它。

我知道有内部异常的异常:

  • 目标调用异常
  • 聚合异常

这里的答案很简单:只要这样做有用,这完全是上下文相关的。对于绝大多数情况,除了报告异常之外,实际上根本不值得对异常进行太多检查;只是"做这件事,哎呀,失败了"——你通常应该比catchIMO 有更多的usingfinally——因为通常除了向上冒泡之外,除了向上冒泡之外,你没有任何有用的事情可以做。

但是,在某些情况下,存在有用的上下文。典型的例子是AggregateExceptionTargetInvocationExceptionTypeInitializationException或任何来自XmlSerializer的东西。这些非常罕见,因此除非您有充分的理由期待它们,否则您不想开始明确检查它们。就您的一般错误报告代码而言:是的,记录内部异常是有意义的,但.ToString()通常会自动执行此操作,IIRC。

作为一些涉及InnerException的真实代码的示例 - 在我的网络代码中有一个场景,我不关心只能通过外部和内部异常的组合来检测的非常具体的情况;when为我做这项工作:

try
{
await _server.RunClientAsync(connection.Transport).ConfigureAwait(false);
}
catch (IOException io) when (io.InnerException is UvException uv && uv.StatusCode == -4077)
{ } //swallow libuv disconnect

(除了那个场景之外的所有内容都是冒泡的(

最新更新