为什么“login和扔”被认为是反模式?

这个问题引发了围绕这篇文章的讨论,我没有收到任何好的答案。

为什么要logging你的exception,然后重新抛出它(当然保留原始的堆栈跟踪)是一个坏主意,如果你不能处理它呢?

我认为答案很大程度上是因为你为什么不能处理它,为什么要捕捉它呢? 为什么不让任何人能够处理它(或者是别无select,只能处理它),如果他们认为这是值得logging的,那么logging下来呢?

如果你抓住并logging并重新抛出它,那么上游代码就无法知道你已经logging了这个exception,所以同样的exception可能会被logging两次。 或者更糟糕的是,如果所有的上游代码遵循相同的模式,那么exception可能被logging任意次数,代码中的每个级别都会logging一次,然后logging下来,然后再次丢弃。

也有人可能会说,因为抛出和捕获exception是相对昂贵的操作,所有这些捕获和重新抛出不会帮助您的运行时性能。 在简洁或可维护性方面也不能帮助你的代码。

如果捕获并重新抛出exception的实体有理由相信它包含的信息不会被进一步logging到调用堆栈中,那么Log-and-throw就是一个很好的模式 – 至less不是以最期望的方式。 有几个原因可能会发生:

  1. 该exception可能会在应用程序层边界被捕获并重新生成,并且可能包含特权信息。 如果数据库层允许一个例外情况出现,例如“试图将重复键”fnord“添加到”用户“字段以到达外部应用程序层(这可能会将其暴露给用户)可能对数据库的内部部分有用,以引发这样的exception和应用程序接口来捕获它,安全地logging它,并重新抛出一个稍微不那么具有描述性的exception。
  2. 例外情况可能是外层可能希望在没有日志logging的情况下处理,但是内层可能知道外层没有的东西,这可能意味着日志logging可能是有用的。 作为一个粗略的例子,一个中间的应用程序层可能被编程为尝试连接到一个服务器,如果这不起作用,请尝试另一个服务器。 当服务器closures以进行维护时,使用“连接失败”消息泛滥应用程序的日志可能没有帮助,尤其是因为从应用程序的angular度来看,一切正常。 将关于连接失败的信息转发到与服务器相关联的日志logging资源可能是有用的,其然后可以过滤日志以产生服务器何时升降的报告,而不是每个单个连接尝试的日志。

我想最简单的原因是你通常有一个顶级的处理程序为你做这个,所以没有必要通过这个exception处理来污染代码。

横切关注的论点基本上是浪费时间来处理与您无关的错误。 最好让错误冒出来,直到find合适的处理程序。

在我看来,唯一一次你应该发现一个exception的地方是你可以对结果做一些有用的事情。 简单地logging日志并没有什么用处,因为你可以把这个工作集中起来。

国际海事组织的logging和抛出明显违反了“最小惊喜原则”。

如果exception在调用堆栈中进一步处理,可能根本不值得一个错误日志条目。 然后find一个错误日志条目是令人困惑的。