【问题标题】:Exception catching: when not to catch them?异常捕获:什么时候不捕获它们?
【发布时间】:2011-11-14 10:09:01
【问题描述】:

我一直在 PHP 的 Zend 框架内为我的应用程序编写一些小型库(一堆类)。我也一直在库的方法本身中捕获这些异常并将它们记录到文件中。

然后我突然遇到了一个问题,即我使用这些库的主应用程序不会因为错误而退出,即使在我预计它们会因致命错误而退出的情况下也是如此。这个问题是下面的代码一直执行到最后——它不应该有。

在库类中捕获并记录大多数错误(特殊情况除外)似乎不是一个好习惯。他们应该总是按原样抛出错误吗?这是一个正确的假设吗?

如果有人能为我回答这个问题,我将不胜感激。

【问题讨论】:

  • 当我的意思是“按原样抛出错误”时 - 我并不是说根本不要抓住它。只是我会让调用者/控制器来捕获错误,而不是在库类中捕获它。

标签: php oop zend-framework exception


【解决方案1】:

在任何语言中,例外的一般哲学是它们传达例外情况。你应该相应地使用它们。

如果您最终将每个函数调用都用try 块包围,那么就有问题了。异常被精确设计为使错误处理逻辑化,并且不需要程序员跟踪所有可能的错误路径。因此,您应该准确地在可以有意义地响应它们的地方捕获异常。

如果您想不出比中止和传播错误更好的方法,那么捕获异常是没有意义的。另一方面,如果您可以对某些错误做出明智的反应,请抓住这些错误,然后重新抛出其他错误。

一个典型的例子是,如果您正在处理大量文件。如果解析逻辑中的任何地方出现错误,您也无能为力,即使解析可能会导致许多函数调用失败。但是,在主循环中,您可以try 解析每个文件,如果有异常,您会捕获该异常,跳过该文件并继续下一个。

如果您正在编写库函数,您可能希望在整个函数周围有一个最后的 try 块;不过,这在某种程度上取决于您。只需清楚地记录用户必须从您的库中获得哪些异常。

【讨论】:

  • 正要回答同样的问题,但这很好地涵盖了它。总而言之,始终处理可以实际处理的异常。
  • 是的 - 并且绝对尝试在所有地方和所有地方捕获异常。如果你使用 C 函数返回值之类的异常,那就有问题了……
【解决方案2】:

捕获和处理所有异常是个好主意。如果您不确定异常是否可以安全忽略(例如,由您自己的代码抛出的异常),请显示错误页面。不要简单地重新抛出它,因为没有什么比向用户呈现空白页面或 Web 服务器的默认错误页面(甚至是 PHP 错误消息)更糟糕的了。

【讨论】:

  • 好的,这意味着我应该设计我的库、模型类,让调用者知道它是否应该捕获?可以说,我的库在设计上没有捕获任何异常 - 我只是让调用者/控制器来执行此操作,这是一个理想的设计吗?
  • @SubratBasnet 如果您在代码中使用 PhpDoc (DocBlocks),则可以使用 @throws 标签。某些语言(如 Java)会“自动”执行此操作,因为您必须在方法/类前面加上“throws”子句,就像使用“extends”子句扩展类一样。
【解决方案3】:

这取决于网站是在生产中还是已发布的产品。例如,您要做的最后一件事是向用户显示堆栈跟踪。如果您预计出现可能导致致命问题的错误,请捕获并处理它。

【讨论】:

  • 同意,但我担心代码设计。假设我的库都没有捕获任何异常 - 我只是让我的控制器进行捕获,这是一个好方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多