【问题标题】:Throw exception without halting execution?抛出异常而不停止执行?
【发布时间】:2012-03-19 06:47:58
【问题描述】:

我正在为我正在进行的项目挖一个坑。我有这个庞大的项目(成千上万行),到处都是 MySQL 错误。我现在正在清理它们。

我有一个所有查询都经过的数据库类,所以我所做的是每当出现 SQL 错误时,我现在就抛出一个异常。问题是我不能停止执行。它必须像往常一样继续,只记录异常,以便我可以跟踪它们并一次修复它们。

我希望set_exception_handler 能做我想做的事,但文档明确表示它会在调用我的处理程序后停止执行。那么我该如何解决呢?

异常可以停止当前函数,但我希望它退出函数,可能返回 null 或 false,然后正常继续,但我需要它来调用我的全局异常处理程序。


澄清一下:

我想从我的数据库类中抛出一个异常(只要出现 SQL 错误)。然后我想记录这个错误和/或在屏幕上显示一条消息,直到我可以修复 SQL 错误,或者将有问题的行包装在 try/catch 中。我不希望它停止执行。如果我只是调用一些error_handler() 函数而不是抛出异常,那么我无法捕获它。如果我立即捕获它(也在 DB 类中),那么我就无法在堆栈的更深处捕获它(除非我重新抛出它,但随后我们又回到了暂停执行状态)。

【问题讨论】:

  • 如果您已经更新了将 MySQL 错误转换为异常的代码,为什么不直接记录错误而不是抛出异常?
  • @pgraham:该死……这是个好问题。原因是如果我不想让它落到全局异常处理程序中,我希望能够捕获异常。另外,我想要一个集中的异常处理和日志记录功能。最后,一旦我清除了错误,我想稍微修改全局异常处理程序,以便它实际上确实死并抛出一个致命错误。
  • @downvoter:想解释一下为什么这是一个糟糕的问题?
  • @alfasin: 1) 我删除了我的帖子,因为在 pgraham 提出上述问题后我意识到它没有意义,2) 这个问题本身并不是为了启发任何人,这就是为什么它是题。如果您认为这是一个坏主意,请将原因作为答案发布,以便它可以帮助他们。对错误信念的问题投反对票可能会阻止其他与我有同样错误想法的人学习。 3)我有调试打印。我想要异常,以便它们可以被捕获(如上面的评论中所述)。
  • 简短的回答是否定的。如果您不能将所有代码包装在 try/catch 块中,那么任何到达顶级异常处理程序的东西都会死掉。我的建议是定义一个可以向其传递异常的日志记录函数。然后,当您将 MySQL 错误转换为异常时,不要抛出异常,而是将其传递给日志记录函数。稍后当您确实需要致命错误时,您只需要更新日志功能以也抛出异常。

标签: php mysql exception exception-handling


【解决方案1】:

如果我理解正确的话:

function myFunction($params) {

    try {

        //your code which throws Exception

    } catch (Exception $e) {

        myErrorFunction($e);
        return false;
    }

}

【讨论】:

  • 不,我认为您不了解我的全部要求。我将把 try/catch 放在哪里?我现在没有时间把它放在每一个 SQL 查询中,所以我必须把它准确地放在我扔它的地方......但是我不能再进一步抓住它,因为我已经抓住了它.我不认为我想做的事情是可能的。
  • 您可以包装整个代码或仅在数据库类中使用它。你有多少种方法? 10? 20?只需用 try catch 包装它们,每次执行它时,例如$db->myCustonQuery(),你就知道如果发生错误,它会抛出一个你可以在其他地方处理的异常。这个答案的真正意义在于,如果您 return false 您将能够继续执行。
  • 如果我包装整个代码,那么当抛出异常时,执行将下降到那个点(catch);我需要它在它停止的地方继续(在投掷时)。有几种方法?什么,在我的数据库课上? 10-20 是一个合理的估计,但是包装这些也不能让我在我想要的地方抓住它。基本上,我希望能够 捕捉到我调用$db->GetSingleRecord() 的位置,但也可以选择,因为对所述函数有数千次调用,而我必须全部完成。那有意义吗?我认为我的要求是不切实际的,但这将是最佳情况。
  • 抛开时间限制,听起来你真的需要重构整个事情。
  • @Ing:我很乐意。不幸的是,时间限制是不容忽视的现实。
【解决方案2】:

我想我找到了解决方法。我可以直接使用异常调用我的处理程序,而不是抛出异常:

global_exception_handler(new MySqlException($error_message)); 

这样我的处理程序仍然会被调用,但会继续执行。

然后仍然可以使用相同的异常处理程序来捕获实际抛出的所有其他异常:

function _global_exception_handler($e) {
    // log error here
}

set_exception_handler('global_exception_handler');

【讨论】:

  • 这有点像添加调试打印,不是吗?
【解决方案3】:

我知道的旧帖子,但我也问过这个问题,发现答案是在您使用 try catch(Exception) 的顶部添加这一行:

使用异常;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多