IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Yii2 关于异常的全局处理 -> 正文阅读

[开发测试]Yii2 关于异常的全局处理

在项目开发中,我们时常需要去监听全局抛出的异常信息,并在后台根据抛出的异常信息对bug进行修复。那么在Yii2中我们如何去设置呢

1、首先我们需要先创建一个自定义异常类,用于处理全局异常

<?php


namespace app\controllers;


use yii\web\Controller;
use Yii;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use app\exceptions\ApiException;
use app\exceptions\HttpException;
use app\exceptions\ApiException;
use Codeception\Util\HttpCode;

class ExceptionController extends Controller
{

    public function __construct($id, $module, $config = [])
    {
        parent::__construct($id, $module, $config);
    }

    public function actionErrorHandler()
    {
        $exception = Yii::$app->errorHandler->exception;

	    //在这里我们可以将异常保存至异常队列,然后根据反馈信息处理异bug
		
		//对不同的异常抛出有不同的响应处理
        switch($exception)
        {
            case $exception instanceof ApiException:
                //响应json
                Yii::$app->response->format = Response::FORMAT_JSON;
                $data = [
                    'code'  =>  $exception->getCode(),
                    'msg'   =>  $exception->getMessage()
                ];

                return $data;
            case $exception instanceof HttpException:
                //响应视图
                return $this->render('error',[
                    'code'  =>  $exception->getCode(),
                    'msg'   =>  $exception->getMessage()
                ]);
            case $exception instanceof ApiException:
                 Yii::$app->response->statusCode = HttpCode::OK;
                 $data = [
                    'code'  =>  $exception->getCode(),
                    'msg'   =>  $exception->getMessage()
                ];

                return $data;
            default:
                echo 'not get exception';
        }
        exit;
    }
}

2、我们需要在全局配置文件(app/config/web.php)中声明异常处理路径

'components'=>[
	//自定义异常处理路径
	'errorHandler'	=>	'exception/error-handler'
]

3、创建两个自定义异常类,用于响应不同类型时,对结果处理。
ApiException(响应JSON数据格式)、HttpException(响应视图数据格式)
ApiException

<?php


namespace app\exceptions;


use Throwable;
use yii\base\Exception;

class ApiException extends Exception
{
    public function __construct($message = "", $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}

HttpException

<?php


namespace app\exceptions;


use Throwable;
use yii\base\Exception;

class HttpException extends Exception
{
    public function __construct($message = "", $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}

4、在入口文件(app\web\index.php)中,将当前模式切换为发布模式(目的是模拟发布环境上,确保异常的正常使用)


defined('YII_DEBUG') or define('YII_DEBUG', false);
defined('YII_ENV') or define('YII_ENV', 'prod');

require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';

$config = require __DIR__ . '/../config/web.php';

(new yii\web\Application($config))->run();

5、测试

 public function actionIndex()
    {
        
        throw new ApiException('123',123);
        //throw new app\exceptions\HttpException('123',123);
       
    }

需要注意的点
1、在抛出异常之前不能更改当前响应数据的格式。例如

Yii::$app->response->format = Response::FORMAT_JSON;

如果这样设置了,那么会导致Yii2抓取不了异常信息

关于如何捕获rest/controller 异常信息

前面我们已经设置了一个全局异常控制器,那么我们希望这个控制器也能捕捉到restFul接口的异常怎么办呢?因为restFul接口继承的控制器是yii\rest\Controller 在抛异常的时候是不会像yii\web\Controller可以控制异常的处理路径的。如下方案解决这个问题。

我们首先创建一个异常 ApiException 用于处理接口异常。

<?php


namespace app\exceptions;


use Throwable;
use yii\base\Exception;

class ApiException extends Exception
{
    public function __construct($message = "", $code = 0, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}

然后在创建一个类(ApiController)继承 yii\rest\Controller 并在其中添加一个钩子,意为在发送数据给终端用户前,先拦截下来(触发yii\web\Response::EVENT_BEFORE_SEND事件),判断当前响应是否包含异常,如果有异常,使用钩子,去异常处理中心(ExceptionHandlerController)勾出异常处理内容,并响应给客户

<?php
namespace app\modules\v1\common\controllers;

use app\controllers\ExceptionController;
use Yii;
use yii\helpers\ArrayHelper;
use yii\rest\Controller;

class ApiController extends Controller
{
    public function __construct($id, $module, $config = [])
    {
        parent::__construct($id, $module, $config);

        /**********************捕获rest controller产生的异常并将其注入至异常控制器*************************************/
        $model = $this;
        Yii::$app->response->on(yii\web\Response::EVENT_BEFORE_SEND,function($event) use ($model){
            if(!empty(Yii::$app->errorHandler->exception))
            {
                $exception = new ExceptionController($model->id,$model->id);
                Yii::$app->response->data = $exception->actionHandler();
            }
        });
    }

    public function behaviors()
    {
        $parentBehaviors = parent::behaviors();

        $behaviors = [
          
        ];

        return ArrayHelper::merge($parentBehaviors,$behaviors);
    }
}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:40:45  更:2022-04-04 12:42:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 1:39:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码