PHP异常没有被捕获

时间:2016-07-01 17:25:39

标签: php exception-handling

我在一个类上工作,通过PHP应用程序进行SVN更改。我通过exec()调用svn命令并尝试在错误时抛出异常以恢复任何更改。

以下是SVN类的相关部分:

private function svn_exec($cmd) {
        $out = array();
        $err = 0;
        exec($cmd, $out, $err);

        if ($err) {
            throw new SVNException("$cmd exited with a status of $err");
        }
    }

自定义Exception,包含在与SVN类相同的文件中:

    class SVNException extends \Exception {
    public function __construct($message = null, $code = 0, \Exception $previous = null) {

        error_log("SVN Error: " . $message);

        parent::__construct("A Subversion error has occurred.", $code, $previous);
    }
}

另一个类中的调用代码:

public function ApplySVNChanges() {
    try {
                $svn->update();

                // Do a bunch more stuff...

                $svn->commit();
            } catch (\utils\SVNException $se) { 
                error_log("Exception caught in SVN class."); // <-- Being logged
                $svn->revert();
                throw $se; // Throw to caller so db changes are rolled back
            }
}

SVN Update正在抛出一个SVNException,然后我才能继续讨论为什么我需要弄清楚我的应用程序崩溃并且没有像它应该那样处理SVNException。根据错误日志,SVNException未处理。对$ svn-&gt; update()的调用是在一个应该捕获SVNExceptions的try / catch块中,所以我很困惑为什么它没有被处理。

  

PHP致命错误:未捕获异常'utils \ SVNException',并显示消息'发生Subversion错误'。在/path/SVNFunctions.php:114 \ nStack trace:\ n#0 /path/SVNFunctions.php(73):utils \ SVNFunctions-&gt; svn_exec('svn update --us ...')\ n#1 /path/CallingClass.php(120)

更新:在捕获异常时将消息添加到catch块以进行记录后,我发现正在捕获SVN异常,但是当重新抛出时,调用它的上面的方法没有捕获它。原始try catch块是另一个方法调用的方法的一部分,该方法使用自己的块来恢复SVN和db更改以使它们保持同步。

try {
        ApplySVNChanges(); // Throws SVNException

        // Database related changes...          

        $db-commit();
    } catch (Exception $e) {
        error_log('Caught Exception in main caller.'); // <-- NOT being logged

        if($e instanceof \core\DatabaseException OR $e instanceof \utils\SVNException) {           
            $db->rollback();
        } else {
            throw $e;
        }
    }

根据错误日志,update命令抛出异常。它被第一个catch捕获,revert被调用,而数据库和SVN异常的调用方法中的catch没有捕获它。

2 个答案:

答案 0 :(得分:1)

你好svn->revert()?可能是svn->revert()正在调用svn->exec或正在做其他事情以使异常重新抛出?

我只是在猜测,但如果恢复失败并抛出SVNException,我认为这里发生了什么......

您可以通过简单地更改catch部分进行测试,例如使用echo "test"; exit;代替$svn->revert();

更新: 更新后,您添加了拼写错误,将$throw se更改为throw $se

public function ApplySVNChanges() {
try {
            $svn->update();

            // Do a bunch more stuff...

            $svn->commit();
        } catch (\utils\SVNException $se) { 
            error_log("Exception caught in SVN class."); // <-- Being logged
            $svn->revert();
            throw $se; // Throw to caller so db changes are rolled back
        }

}

答案 1 :(得分:0)

发现问题。 try-catch块包含对抛出SVNException的其他方法的调用:

catch (Exception $e) {
        if($e instanceof \core\DatabaseException OR $e instanceof \utils\SVNException) {           
            $db->rollback();
        } else {
            throw $e;
        }
}

实际上并没有捕获SVNExceptions或DatabaseExceptions。在Exception之前添加反斜杠修复了问题:

catch (\Exception $e) {

正在按预期处理SVNExceptions。

编辑:对于好奇,对另一个问题的回答:https://stackoverflow.com/a/12170579/5530617实际上解决了导致$ svn-&gt; update()通过添加--config-dir引发异常的问题shell命令的选项。