PHP:嵌套的try-catch在函数中不起作用

时间:2014-01-13 10:26:41

标签: php

最近我开始玩Exceptions及其处理。一切似乎工作得很好,但我刚刚碰到了一堵砖墙,我不确定是否有解决方案可以解决我的问题,或者我应该重新制作我的代码库。

情况:

我正在try块中执行一小段代码,我正在捕获所有异常,只是记录/输出错误。我正在尝试执行一个从数据库中删除对象的函数:

  1. 删除了关系;
  2. 删除对象。
  3. 我想要完成的是:如果删除对象失败 - 恢复以前删除的关系。

    我认为将嵌套的try-catch块放在正在执行最终删除的位置的函数中我会捕获异常并还原更改,但是这在函数内部不起作用而且它只是忽略了try -catch块并进入顶部。 HOWEVER :当我将相同的代码放在函数之外时,它的工作正常并且与预期的一样!

    下面是两段代码 - 工作但不工作。

    编辑:我忘了提到我故意在“路由器”DELETE查询中犯了一个语法错误,它总是在“$ status_r = \ sys \ database \ query($ query, $ db,$ elem_t,$ elem);“执行。在第一种情况下,它忽略函数“delete”中的try-catch块,并转到调用函数的顶部try-catch块。

    不按预期工作

    try
    {
        $db = \sys\database\connect();
        $status = ips\routers\delete($id, $db);
        echo "success";
        \sys\core\log_action("router_delete", "success", "Router '$id' successfully deleted", $db);
    }
    catch (Exception $ex)
    {
        echo (sys\errors\is_error($ex->getMessage())) ? sys\errors\parse($ex->getMessage()) : $ex->getMessage();
        \sys\core\log_action("router_delete", "failure", $ex->getMessage(), $db);
    }
    
    删除功能中的

    代码:

    function delete($id, &$db = false)
    {
        // Check if Any Interfaces are set on this router
        if (\ips\interfaces\exists(array("router", $id), $db) !== false)
            throw new \Exception(\sys\errors\exist("Router has active interfaces and cant be removed!"));
    
        $curr_ip_id = \ips\ips\get(array("router_id", $id), "id", $db);
        if (!\sys\validation\validate("numeric", $curr_ip_id[0]['id']))
            throw new \Exception(\sys\errors\database());
    
        $status = \ips\ips\revoke($curr_ip_id[0]['id'], NULL, $db);
        if ($status === true)
        {
            // if we get an error we need to revert changes - aka rebind IP to router
            try
            {
                $query = "DELETE FROM routers WHERE i = ?";
                $elem_t = "i";
                $elem = array($id);
                $status_r = \sys\database\query($query, $db, $elem_t, $elem);
                if ($status_r === true)
                    return true;
                else
                    throw new \Exception();
            }
            catch (Exception $ex)
            {
                $status_rebind = \ips\ips\set_owner(array("id", $curr_ip_id[0]['id']), $id, "router", $db);
                if ($status_rebind === true)
                    throw \Exception(\sys\errors\database("Failed Deleting router at the last step. IP reassigned successfully!"));
                else
                    throw \Exception(\sys\errors\database("Failed Deleting router at the last step. IP reassigned failed!"));
            }
        }
        else
            throw new \Exception(\sys\errors\database("Failed revoking IP address from router!"));
    }
    

    按预期工作

    try
    {
        $db = \sys\database\connect();
    
        if (\ips\interfaces\exists(array("router", $id), $db) !== false)
            throw new \Exception(\sys\errors\exist("Router has active interfaces and cant be removed!"));
    
        $curr_ip_id = \ips\ips\get(array("router_id", $id), "id", $db);
        if (!\sys\validation\validate("numeric", $curr_ip_id[0]['id']))
            throw new \Exception(\sys\errors\database());
    
        $status = \ips\ips\revoke($curr_ip_id[0]['id'], NULL, $db);
        if ($status === true)
        {
            // if we get an error we need to revert changes - aka rebind IP to router
            try
            {
                $query = "DELETE FROM routers WHERE i = ?";
                $elem_t = "i";
                $elem = array($id);
                $status_r = \sys\database\query($query, $db, $elem_t, $elem);
                if ($status_r === true)
                    return true;
                else
                    throw new \Exception();
            }
            catch (Exception $ex)
            {
                $status_rebind = \ips\ips\set_owner(array("id", $curr_ip_id[0]['id']), $id, "router", $db);
                if ($status_rebind === true)
                    throw new \Exception(\sys\errors\database("Failed Deleting router at the last step. IP reassigned successfully!"));
                else
                    throw new \Exception(\sys\errors\database("Failed Deleting router at the last step. IP reassigned failed!"));
            }
        }
        else
            throw new \Exception(\sys\errors\database("Failed revoking IP address from router!"));
    
    }
    catch (Exception $ex)
    {
        echo (sys\errors\is_error($ex->getMessage())) ? sys\errors\parse($ex->getMessage()) : $ex->getMessage();
        \sys\core\log_action("router_delete", "failure", $ex->getMessage(), $db);
    }
    

    我不确定为什么try-catch在函数内部不起作用。任何帮助都将受到高度赞赏。

    提前致谢!

0 个答案:

没有答案