自定义异常未被捕获

时间:2017-01-09 17:02:41

标签: php codeigniter exception exception-handling codeigniter-3

拥有此自定义异常:

class TokenException extends Exception 
{
    public $token;

    public function __construct($message, $token)
    {
        $this->message = $message;
        $this->token = $token;

        parent::__construct($message, 1);
    }
}

这个代码使用它:

public function visit()
{
    try {

        // validate input token

        // actions

    }
    catch (TokenException $e) {

        logdebug('TokenException'); // logs "TokenException"

        $res['relogin'] = 1;
        $res['error'] = $e->getMessage() . ' token: ' . $token;

    }
    catch (Exception $e) {

        logdebug('Exception'); // logs "Exception"

        $res['error'] = $e->getMessage() . ' token: ' . $token;

    }
    finally {
        $this->output($res);
    }
}

尽管在验证过程中它抛出了TokenException:

throw new TokenException('Invalid token. It does not belong to any user', $token);

它跳过TokenException catch并输入Exception,显示令牌错误消息。

这里有什么问题?

编辑

这里有更详细的代码。它使用Codeigniter MVC模式:

这是涉及的公共API的父控制器:

class Apicontroller extends MX_Controller
{

    /**
     * 
     * @var stdClass $user
     */
    protected $user;


    /**
     * Load user model
     */
    public function __construct()
    {
        $this->load->model('users_model', 'users');
    }


    protected function output($data)
    {
        header('Content-Type: application/json');
        header('Access-Control-Allow-Origin: *');
        echo json_encode($data);
    }

    // other code...

}

未捕获异常的代码:

require_once __DIR__ . '/Apicontroller.php';
require_once __DIR__ . '/../TokenException.php';


class Apisellercontroller extends Apicontroller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('apiseller_model', 'apiseller');
        $this->load->model('log_model', 'logger');
        $this->load->model('alerts_model', 'alerts');
    }

    // inserts/updates data of a visit made by a sales agent to a client from an external app
    public function visit()
    {
        try {

            $res = [];

            // get api token and user
            $user = $this->input->post('user');
            $token = $this->input->post('token');
            $visit = $this->input->post('data');

            $this->validateRequest($user, $token, $visit);

            // Get user by token from the users model
            $this->user = $this->users->getByToken($token);

            $this->apiseller->setUser($this->user);

            $visit['sellers_id'] = $this->apiseller->getSeller()->id;

            // Insert/update
            $this->load->model('visits_model');

            $res['id'] = $this->visits_model->save($visit);

        }
        catch (TokenException $e) {

            $res['relogin'] = 1;
            $res['error'] = $e->getMessage() . ' token: ' . $token . ' user: ' . $user;

        }
        catch (Exception $e) {

            $res['error'] = $e->getMessage() . ' token: ' . $token . ' user: ' . $user;

        }
        finally {
            $this->output($res);
        }
    }

    private function validateRequest($user, $token, $data)
    {
        if (empty($user)) {
            throw new Exception('User id not received');
        }
        if (empty($token)) {
            throw new Exception('Session token not received');
        }
        if (empty($data)) {
            throw new Exception('Request data not available');
        }

        // Check token validity for user
        $this->apiseller->checkTokenValid($user, $token);
    }

    // other methods
}

用于检查令牌有效性的模型(如果令牌无效,则会抛出TokenExcepcion):

require_once __DIR__ . '/Api_model.php';
require_once __DIR__ . '/../modules/api/TokenException.php';

class Apiseller_model extends Api_model
{

    public function checkTokenValid($currentUser, $token)
    {
        $user = $this->getUserByToken($token);
        if (empty($user)) {
            throw new TokenException('User not found for specified token', $token);
        }

        if ($user->name != $currentUser) {
            throw new TokenException("Invalid token. It doesn't match the specified user", $token);
        }
    }

    // other code...

}

2 个答案:

答案 0 :(得分:1)

您是否尝试过parent :: __ construct($ message,1);作为第一线?如果没有,我理解它会覆盖先前设置的属性......

class TokenException extends Exception 
{
    public $token;

    public function __construct($message, $token)
    {
        parent::__construct($message, 1);
        $this->message = $message;
        $this->token = $token;
    }
}

答案 1 :(得分:1)

抛出的异常显然不是TokenException的一个实例,因此我建议你看一下stacktrace来看看,这个异常真的来自:

http://php.net/manual/en/exception.gettraceasstring.php

 app.directive('tablesClick', function () {
     return {
         restrict: 'E',
         template: [
             '<table>',
             '<tr>',
             '<td> <label>This is local value: {{btnval}}</label><br/><input ng-model="btnval" type="text" /><button type="button" ng-click="func()" >reverse</button>',
             '</tr>',
             '</table> '
         ].join(''),
         scope: {
             btnval: '='
         },
         controller: function ($scope, $element) {
             $scope.func = function () {                                              
                 $element;
             };
         },
         link: function (scope, element, attrs) {
      }
    }
});

您还可以检查您的例外是否已作为“上一个”传递;这意味着它包含在你的代码的其他部分:

http://php.net/manual/en/exception.getprevious.php

echo $e->getTraceAsString();die;