优雅的输出错误-assert

简介: 优雅的输出错误-assert

在正常情况,我们会通过,if,else进行判断一个接口的条件是否满足,不满足则输出错误,例如

在IM系统中,申请入群接口,需要以下判断:

$param = $this->request()->getRequestParam();
$groupModel = new UserGroupModel();
//获取群信息
$groupInfo = $groupModel->getOneByGroupHash($param\['groupHash'\]);
if (empty($groupInfo)){
    $this->writeJson(HttpStatus::CODE\_BAD\_REQUEST, \[\], '群组数据不存在');
    return true;
}
//判断被封
if($groupInfo->state!=1){
    $this->writeJson(HttpStatus::CODE\_BAD\_REQUEST, \[\], '群已经被封');
    return true;
}
//判断是否为本群成员
$groupUserModel = new GroupUserModel();
$userInfo = $groupUserModel->getOneByGroupIdAndUserId($groupInfo->groupId, $this->who->userId);
if ($userInfo){
    $this->writeJson(HttpStatus::CODE\_BAD\_REQUEST, \[\], '你已经是本群成员');
    return true;
}

可以看出,这里面有着非常多的if else,return,writeJson等重复代码.那么,有没有一个办法,进行if,else等封装,直接一行代码实现 判断+输出错误呢?

assert断言

断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。

断言比较常见的场景在于unit单元测试,例如在easyswoole/redis组件中的tests 单元测试用例中:

image.png

在此示例中,可以看出,断言的作用在于确保程序的正常执行,如果出错则代表程序有问题,需要修bug

业务断言

我们可以通过断言(确保其条件正确,使得程序往下执行)的说法,在业务中封装:

function assert($condition,$msg){
    //断言条件一定满足,不满足则抛出异常
    if ($condition!==true){
        throw new Exception($msg);      
    }
}

上面的代码优化:

$param = $this->request()->getRequestParam();
$groupModel = new UserGroupModel();
//获取群信息
$groupInfo = $groupModel->getOneByGroupHash($param\['groupHash'\]);
//注意1:我们需要断言的是true,!!的作用是将正常数据转为bool类型
//断言一定存在groupInfo
assert(!!$groupInfo,'群组数据不存在');
//断言state一定为1
assert($groupInfo->state==1,'群组数据不存在');
//判断是否为本群成员
$groupUserModel = new GroupUserModel();
$userInfo = $groupUserModel->getOneByGroupIdAndUserId($groupInfo->groupId, $this->who->userId);
//断言一定不在群里
assert(!$userInfo,'你已经是本群成员');

在此时,我们已经将我们的判断代码,优化成了一行,在assert函数中,会将不符合预期的数据,通过异常抛出,我们需要通过拦截异常,来实现输出前端需要的数据格式:

try{
    $param = $this->request()->getRequestParam();
    $groupModel = new UserGroupModel();
    //获取群信息
    $groupInfo = $groupModel->getOneByGroupHash($param\['groupHash'\]);
    //注意1:我们需要断言的是true,!!的作用是将正常数据转为bool类型
    //断言一定存在groupInfo
    assert(!!$groupInfo,'群组数据不存在');
    //断言state一定为1
    assert($groupInfo->state==1,'群组数据不存在');
    //判断是否为本群成员
    $groupUserModel = new GroupUserModel();
    $userInfo = $groupUserModel->getOneByGroupIdAndUserId($groupInfo->groupId, $this->who->userId);
    //断言一定不在群里
    assert(!$userInfo,'你已经是本群成员');
}catch (\\Throwable $throwable){
    //拦截抛出的异常,然后直接输出json 错误消息
    $this->writeJson(HttpStatus::CODE\_BAD\_REQUEST, \[\], $throwable->getMessage());
    return true;
}

注意:上面的代码为简单实现,如果需要在项目中使用,请实现自定义异常类,捕捉自定义的异常,相关较为完善的代码已开源:

https://github.com/tioncico/LogicAssert  仅供参考

其他

需要注意的是,断言的意思为:  断定条件为真,使代码继续往下执行,断言抛出异常为,条件错误才抛出.

如果觉得拗口,可以改为logicCheck,直接判断为真则抛出异常即可

目录
相关文章
|
Kubernetes 网络协议 关系型数据库
Kubernetes----ExternalName类型的Service
Kubernetes----ExternalName类型的Service
2648 0
|
算法 量子技术 数据库
量子计算:从理论到实践的深度解析
在当前科技迅猛发展的时代,量子计算作为一项颠覆性的技术正在不断引起广泛关注。本文旨在深入探讨量子计算的理论基础、关键技术和实际应用,并分析其未来发展前景及面临的挑战。通过对量子比特、纠缠态和量子门操作等核心概念的详细阐述,读者将能够全面理解量子计算的基本原理和潜在影响。
323 27
|
Java Serverless Kotlin
Kotlin中的异常处理
Kotlin中的异常处理
324 1
|
11月前
|
数据采集 存储 数据管理
CDGA|如何实施非常精准的数据治理策略?
精准的数据治理需要企业从设定明确目标、制定适应性策略、构建完善组织结构、制定严谨制度流程、采用先进技术工具、加强事前预防、推动数据驱动决策以及建立健全监督与评估机制等多个方面入手。只有这样,企业才能有效应对数据时代带来的挑战,充分释放数据价值,为组织的可持续发展提供有力支撑。
EMQ
|
开发工具
MQTT 5.0 报文解析 04:PINGREQ 与 PINGRESP
除了用于连接、发布和订阅的控制报文,MQTT 还有一类报文用于在客户端和服务端之间模拟心跳,以达到保持连接的目的,它们分别是 PINGREQ 报文和 PINGRESP 报文,我们通常也会称它们为心跳报文。
EMQ
419 0
MQTT 5.0 报文解析 04:PINGREQ 与 PINGRESP
|
消息中间件 监控 前端开发
小巧快速 Kafka GUI 客户端推荐
想要查看Topic里的消息却找不到软件,想要查看或更新Broker、Topic配置,想要监控Broker服务器状态?试试下面的Kafka GUI工具——Kafka Assistant
1114 1
小巧快速 Kafka GUI 客户端推荐
|
前端开发 NoSQL 数据库
如何设计 QQ、微信、微博、Github 等等,第三方账号登陆 ?(附表设计)
如何设计 QQ、微信、微博、Github 等等,第三方账号登陆 ?(附表设计)
185 1
|
Web App开发 设计模式 测试技术
python自动化测试实战 —— 自动化测试框架的实例
python自动化测试实战 —— 自动化测试框架的实例
314 0
|
存储 消息中间件 监控
架构设计第42讲:美团 - 可视化全链路日志追踪
架构设计第42讲:美团 - 可视化全链路日志追踪
649 0
|
设计模式 存储 前端开发
MVC-架构
MVC-架构
257 0