首页 文章

如何更改JSON请求Cakephp 3的错误响应结构

提问于
浏览
1

在我的router.php中,我已经使用这样的路由文件扩展启用了json扩展

Router::prefix('api', function (RouteBuilder $routes) {
    $routes->extensions(['json']);
    $routes->fallbacks('DashedRoute');
});

一切都很好 . 当我想给出错误消息时,我使用这个JSON结构

{
    "data": {
        "error": "Please provide username"
    }
}

当我抛出ForbiddenException时,我得到了这样的结构

{
    "message": "Forbidden",
    "url": "/sfworxerp/api/v1/attendances/getEmployeesAttendance.json",
    "code": 403
}

但我需要这种格式 .

{
    "data": {
        "error": "Forbidden",
        "code": 403
    }
}

到目前为止我已经完成了

我已经创建了这样的自定义ExceptionRenderer

命名空间App \ Error;

use Cake\Error\ExceptionRenderer;

class AppExceptionRenderer extends ExceptionRenderer
{

    public function forbidden($error)
    {

        return 'test';
    }

}

并将其添加到我的app.php文件中

'Error' => [
    'errorLevel' => E_ALL & ~E_DEPRECATED,
    'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
    'skipLog' => [],
    'log' => true,
    'trace' => true,
],

当我将字符串'test'的值更改为数组时,它会抛出错误

致命错误:在第186行的F:\ public_html \ sfworxerp \ vendor \ cakephp \ cakephp \ src \ Error \ ErrorHandler.php中的非对象上调用成员函数send()

2 回答

  • 8

    数组不是自定义错误方法的有效返回类型

    仔细查看文档,它指出自定义异常渲染器方法的两个可能的返回值:

    [...]异常处理方法将异常作为参数处理 . 您的自定义异常呈现可以返回字符串或Response对象 . 返回响应将使您完全控制响应 . [...]

    *强调我的

    Cookbook > Error & Exception Handling

    所以如果你必须通过 $this->controller->response 对象 Build 正确的响应并返回它 .

    修改序列化的内容和方式

    但是,此类自定义方法确实会影响所有错误响应,而不仅仅是序列化的响应 . 对于一种侵入性较小的方法,您最好将其挂钩,例如 _outputMessage() ,并修改视图变量和序列化配置以满足您的需求,类似于以下内容:

    protected function _outputMessage($template)
    {
        $this->controller->set('data', [
            'error' => $this->controller->viewVars['message'],
            'code' => $this->controller->viewVars['code']
        ]);
        $this->controller->set('_serialize', ['data']);
    
        return parent::_outputMessage($template);
    }
    

    这将为每个序列化错误响应(无论是JSON,XML,无论如何)提供所需的结构,同时使常规错误响应不受影响 . 这当然只是一个非常基本的例子,但你应该明白这一点 .

  • 1

    您需要覆盖 render() 方法

    use Cake\Error\ExceptionRenderer;
    
    class AppExceptionRenderer extends ExceptionRenderer
    {
    
        public function unauthorized()
        {
            // do some exception specific here
        }
    
        public function render()
        {
            // You can output here your desired response.
            // You can access exception by calling $this->exception
            // For example...
    
            $this->controller->set('response', ['foo' => 'bar']);
            $this->controller->set('_serialize', 'response');
    
           return $this->controller->response;
        }
    }
    

相关问题