【问题标题】:Is sending error report from PHP Exception __destruct() method a Good or Bad Idea?从 PHP Exception __destruct() 方法发送错误报告是好主意还是坏主意?
【发布时间】:2011-06-27 12:40:53
【问题描述】:

我正在为我的应用程序设计一个错误处理系统。 我想以异常为基础,并且我想通过电子邮件收到有关我没有预料到的每个异常的通知。

我想到了一门课:

class My_Exception extends Exception {

    private $sendErrorReport = true;

    public function __destruct() {
        if ($this->sendErrorReport) {
              // send the error report by email
        }            
    }

    public function cancelErrorReport() {
        $this->sendErrorReport = false;
    }

} 

我想做这样的事情:

try { 
   do_something_that_can_throw_exception();
catch (My_Exception $e) {
   if ($e->getCode() == I_KNOW_WHAT_TO_DO ) {
        react_to_exception();
        $e->cancelErrorReport();   
   } else {
        show_error_message($e->getMessage());
   }
}

所以,基本上,当异常发生并且系统知道该怎么做时,它不会打扰我作为开发人员。但是当系统无法处理某些事情时,我会收到通知。 我不想将通知我的代码放在 catch 子句中,因为我确定我会在某个地方忘记它...

我能确定异常__destuct方法会被调用吗?

异常的__destruct方法是实现这个目标的好方法吗?

有没有更好的方法可以实现这一目标?

【问题讨论】:

    标签: php exception destructor


    【解决方案1】:

    不,这不是一个好主意。

    您最好的选择是替换未处理的异常处理程序。见set_exception_handler. 如果您捕获异常然后改变主意并希望将异常留给异常处理程序(就像您在示例中所做的那样,在分析错误代码时),您总是可以重新抛出异常。当然,更好的选择是对异常进行子类化,而不是依赖错误代码。

    【讨论】:

    • 谢谢。不幸的是,set_exception_handler 不是一个选项,因为应用程序已经设置并运行,并且在我之前的某个人犯了一个设计错误,并且每个异常都被捕获并且消息总是显示给用户,然后就可以到达 set_exception_handler。不好的是,每个 Controller 都有自己的 catch 代码,所以我不能轻易将错误报告代码放在那里。子类可能是一种方法。我会考虑一下。但它也有缺点,我必须决定在我抛出异常的地方发送或不发送错误报告,而不是在我捕获它的地方。
    • @SWilk 我不明白你的解决方案是如何应用的。您已经必须更改所有 catch 以便取消/不取消错误报告,并且您必须更改异常层次结构,如果使用内置异常类型,这甚至可能是不可能的,例如 ExceptionRuntimeException等。
    • 关于内置异常的要点。至于更改“所有缓存”,这还不错,因为我想取消错误报告的地方很少。但你是对的。我需要重新考虑这一点。
    【解决方案2】:

    为什么不简单地向 Exception 类添加一个方法,以便在调用它时发送电子邮件? 比如:

    class My_Exception extends Exception {
    
        private $sendErrorReport = true;
    
        public function __destruct() {
            if ($this->sendErrorReport) {
                  // send the error report by email
            }            
        }
    
        public function cancelErrorReport() {
            $this->sendErrorReport = false;
        }
    
        public function sendEmail()
        {
            mail(....., $this->getMessage());
        }
    
    } 
    

    然后你做类似的事情:

    try { 
       do_something_that_can_throw_exception();
    catch (My_Exception $e) {
       if ($e->getCode() == I_KNOW_WHAT_TO_DO ) {
            react_to_exception();
            $e->cancelErrorReport();   
       } else {
            $e->sendEmail();
       }
    }
    

    【讨论】:

    • 我想我会忘记在某些地方调用 sendEmail() 方法。或者公司里的一些新人会。
    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 2015-04-29
    • 1970-01-01
    • 2010-11-23
    • 2014-02-27
    • 2011-10-26
    • 1970-01-01
    • 2019-11-11
    相关资源
    最近更新 更多