例外:这是一个好习惯吗?

时间:2008-09-19 16:43:42

标签: php language-agnostic exception exception-handling error-handling

这是用PHP编写的,但它确实与语言无关。

try
{
    try
    {
        $issue = new DM_Issue($core->db->escape_string($_GET['issue']));
    }
    catch(DM_Exception $e)
    {
        throw new Error_Page($tpl, ERR_NOT_FOUND, $e->getMessage());
    }
}
catch(Error_Page $e)
{
    die($e);
}

嵌套试试,抓住阻止好的做法跟随?对于错误页面来说似乎有点笨重 - 但是如果发生错误,我的Issue Datamanager会抛出异常,并且我认为这是一种检测错误的好方法。

Error_Page异常只是一个错误页面编译器。

我可能只是迂腐,但您认为这是报告错误的好方法吗?如果可以的话,您能建议更好的方式来编写错误吗?

由于

7 个答案:

答案 0 :(得分:10)

您正在使用页面逻辑的例外,我个人认为这不是一件好事。应该使用异常来指示发生错误或意外事件的时间,而不是控制错误页面的输出。如果要根据例外生成错误页面,请考虑使用set_exception_handler。任何未捕获的异常都通过您指定的任何回调方法运行。请记住,这并不能阻止异常的“致命性”。在通过回调传递异常后,执行将在任何未捕获的异常后正常停止。

答案 1 :(得分:2)

我认为你最好不要筑巢。如果您期望多个异常类型,则有多个异常捕获。

try{
  Something();
}
catch( SpecificException se )
{blah();}
catch( AnotherException ae )
{blah();}

答案 2 :(得分:2)

理想情况是在可以处理它们的级别捕获异常。不是之前(浪费时间),而不是之后(你失去了背景)。

因此,如果$ tpl和ERR_NOT_FOUND是仅在新的DM_Issue调用附近“已知”的信息,例如因为在其他地方您创建了DM_Issue并且想要ERR_SOMETHING_ELSE,或者因为$ tpl的值不同那么你就是在正确的地方捕捉到第一个例外。

如何从那个地方到死亡是另一个问题。另一种选择就是死在那里。但是如果你这样做那么就没有机会干预代码在错误之后但在退出之前做任何事情(例如以某种方式清除某些内容或修改错误页面)。拥有明确的控制流程也很好。所以我觉得你很好。

我假设你的例子不是一个完整的应用程序 - 如果是,那么它可能不必要地冗长,你可能会死在DM_Exception catch子句中。但对于一个真正的应用程序,我赞同不仅仅是在不知名的地方死亡的原则。

答案 3 :(得分:0)

根据您的需要,这可能没问题,但我一般都非常犹豫要捕获异常,将消息包装在新的异常中,并重新抛出它,因为您从原始异常中丢失了堆栈跟踪(和可能的其他)信息在包装异常中。如果您确定在检查包装异常时不需要该信息,那么它可能没问题。

答案 4 :(得分:0)

我不确定PHP,但在例如C#你可以拥有多个catch-Block,因此不需要嵌套的try / catch-combination。

一般来说,我认为使用try / catch / finally进行错误处理总是常识,也是为了“仅显示”错误页面。这是一种处理错误并避免崩溃时出现奇怪行为的干净方法。

答案 5 :(得分:0)

我不会在未找到的问题上抛出异常 - 它是应用程序的有效状态,并且您不需要堆栈跟踪来显示404.

您需要捕获的是意外故障,例如sql错误 - 当异常处理派上用场时。我会改变你的代码看起来更像这样:

try {
    $issue = DM_Issue::fetch($core->db->escape_string($_GET['issue']));
}
catch (SQLException $e) {
    log_error('SQL Error: DM_Issue::fetch()', $e->get_message());
}
catch (Exception $e) {
    log_error('Exception: DM_Issue::fetch()', $e->get_message());
}

if(!$issue) {
    display_error_page($tpl, ERR_NOT_FOUND);
}
else
{
    // ... do stuff with $issue object.
}

答案 6 :(得分:0)

仅当存在潜在的站点破坏事件时才应使用异常 - 例如数据库查询未正确执行或某些内容配置错误。一个很好的例子是Apache进程无法写入缓存或日志目录。

这里的想法是,开发人员的例外情况是暂停可能破坏整个站点的代码,以便您可以在部署之前修复它们。它们也是健全性检查,以确保如果环境发生变化(即有人改变缓存文件夹的权限或更改数据库方案),网站会在它损坏任何内容之前停止。

所以,不;嵌套的catch处理程序不是一个好主意。在我的页面中,我的index.php文件将其代码包装在try ...缓存块中 - 如果发生了不好的事情,它会检查它是否在生产中;并通过电子邮件发送给我并显示一般错误页面,或者在屏幕上显示错误。

请记住:PHP不是C#。对于包含状态的应用程序,C#(对于ASP.net来说是例外(hehe,没有双关语:p)) - 而PHP是一种无状态脚本语言。