Yii2.0 errorAction 和 response=Json 配置冲突

Yii2.0 errorAction 和 response=Json 配置冲突

新建了一个 webapp 对外提供接口服务, 这里没有选用rest/controller, 因为现实项目中, 所有请求均使用了 POST 方式. 因此, 选用 web/controller.

在 web.php 文件中进行了如下配置:

'errorHandler' => [
    'errorAction' => 'site/error',
],
'response' => [
    'format' => yii\web\Response::FORMAT_JSON,
    'charset' => 'UTF-8',
    'on afterSend' => function() {
        \YII::error(['upstream_time' => \YII::getLogger()->getElapsedTime()], 'upstream_time');
        \YII::error(\YII::getLogger()->getProfiling(['yii\db\Connection::open']), 'database_connection');
    },
],

errorAction 主要逻辑如下:

class ErrorAction extends \yii\web\ErrorAction
{
    public function run()
    {
        $enum = ExceptionEnum::_500_UNKNOWN_INTERNAL;
        $template = array(
            'error' => array(
                'errno' => '500-' . $enum['cd'],
                'errmsg' => $enum['msg'],
            ),
            'data'=>array(),
        );

        \YII::$app->getResponse()->format = (Response::FORMAT_JSON);

        $exception = $this->exception;
        if($exception === null) {
            return $template;
        }
        if ($exception instanceof \yii\web\HttpException) {
            $code = $exception->statusCode . '-' . $exception->getCode();
        }else {
            $code = '500-' . $exception->getCode();
        }
        $template['error']['errno'] = $code;

        if ($exception instanceof \Exception) {
            $message = $exception->getMessage();
        }else{
            $message = \Yii::t('yii', $this->defaultMessage);
        }
        $message = strpos($message, 'SQLSTATE')!==false ? '数据库读写错误!' : $message;
        $template['error']['errmsg'] = $message;
        return $template;
    }
}

配置完成后, 直接访问接口, 发现并未按照 errorAction->run() 处理结果. 追本溯源发现, 在web\ErrorHandler->renderException()中:

$useErrorView = $response->format === Response::FORMAT_HTML && (!YII_DEBUG || $exception instanceof UserException);
if ($useErrorView && $this->errorAction !== null) {
    $result = Yii::$app->runAction($this->errorAction);
    if ($result instanceof Response) {
        $response = $result;
    } else {
        $response->data = $result;
    }
} 

只有在$response->format === Response::FORMAT_HTML情况下, 才会由配置中的 errorAction 进行处理.

修改办法

使用 web/controller, ErrorAction 中修改代码:

\YII::$app->getResponse()->format = (Response::FORMAT_JSON);

这样, 默认的响应格式是 html, 进入 ErrorAction 后再修改格式, 这样最终输出的是 json 格式.

参考

errorHandler is skipped when response format is JSON #14395

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值