它通常归结为一个简单的问题:
这个功能可能会“合法地”失败,还是任何失败都是真正错误的迹象?
如果一个函数需要某种类型的输入并且永远不应该使用不同类型的输入来调用,那么任何未能提供正确输入的行为都是InvalidArgumentException
. 对于不直接处理用户输入的函数尤其如此。这对类型提示更有效。
如果一个函数在给定正确输入的情况下应该总是产生某个结果,那么该函数产生该结果的任何失败都是一种RuntimeException
或LogicException
或某种其他类型的异常。
如果一个函数可能会或可能不会产生某种结果,false
那么它就是一个合法的返回值。处理用户输入并因此获得非常任意输入值的函数通常可以返回false
.
一些例子:
getDatabaseConnection()
RuntimeException
如果无法建立与数据库的连接,则抛出 a 或类似内容是完全正确的。这是一种特殊情况,在这种情况下无法继续工作。
transformFooIntoBar(Foo $foo)
Bar
无论出于何种原因,如果它无法返回实例,则抛出某种形式的异常是正确的。该函数具有明确的目的和类型检查的输入值。如果它不能在如此明确的条件下完成其工作,那么显然是有问题,必须加以修复。因此,一个例外。
checkIfUserExists($id)
可能会返回false
,因为它的工作是返回一个大拇指或大拇指向下。鉴于此职位描述,用户不存在并不是例外情况。
在哪里捕获抛出的异常取决于您要在哪里处理它。数据库连接错误可能应该在调用堆栈的最顶部捕获,因为如果数据库关闭,您可能无法做任何事情。
另一方面,如果某个模块正在调用某个子模块并且一半预计该子模块会失败和/或有一个应急计划以防它失败,则该模块可能会捕获子模块的异常并继续执行其工作。例如getRSSUpdates()
调用一个HTTP::fetchContents($url)
. 如果 URL 返回 404,则HTTP
模块可能会抛出异常,因为在这些情况下它无法返回内容。该getRSSUpdates()
函数为此做好了准备,并将这种情况处理为“此时没有更新”。