Hyperf异常类,抛出异常并中断执行
在我们的传统的php框架中,我个人习惯代码需要分层的。
例如分为 Controller层,Service层,Model层。
Controller层就是做个参数接收啊,参数验证之类的事情,然后Service层才来做我们的业务逻辑,Model就是在数据库里面取数据。
在我的传统习惯中,如果Controller通过了数据验证,然后把参数交给Service处理,如果Service成功处理了,就return给Controller处理好的或者取到的数据,再通过reponse交给用户。
那么如果Service处理过程中,比如用户需要购买一件商品,商品id,购买数量都通过了验证了,但是钱不够了,那么就要return给controller错误信息,然后再由控制器去返回给用户,但是如果层级多了呢,一层一层返回是不是很恼火,这个业务错误就不能再这么搞了。就需要Service来做验证,告诉用户,余额不足。
在Laravel项目中我喜欢用一个
/**
* 终止程序并返回信息
*/
public static function returnError(string $msg = '操作失败', int $code = 400, $data = [])
{
$data = [
'msg' => $msg,
'code' => $code,
'data' => $data
];
exit(json_encode($data, JSON_UNESCAPED_UNICODE));
}
直接在Service中 returnError了,中断运行并返回错误信息,但是在Hyperf中,再用exit就不行了,找遍了百度都没找到前辈怎么处理的。
那还是算了,最爱的exit不能用了,还是老老实实的抛异常吧。。。。
下面上代码
新建一个MyException类
<?php
/**
* Author:陈杰
* Blog:http://blog.95shouyou.com
* Email:823380606@qq.com
* Git:https://gitee.com/chen95
* Date:2020/12/9 0009
* Time:12:35
*/
namespace App\Exception\Handler;
use Hyperf\Server\Exception\ServerException;
class MyException extends ServerException
{
public $data = [];
public function __construct($message = "操作失败", int $code = 400, $data = [])
{
$this->message = $message;
$this->code = $code;
$this->data = $data;
}
}
然后再建一个BaseExceptionHandler类
<?php
/**
* Author:陈杰
* Blog:http://blog.95shouyou.com
* Email:823380606@qq.com
* Git:https://gitee.com/chen95
* Date:2020/12/9 0009
* Time:12:34
*/
namespace App\Exception\Handler;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;
class BaseExceptionHandler extends ExceptionHandler
{
public function handle(Throwable $throwable, ResponseInterface $response)
{
// 判断被捕获到的异常是希望被捕获的异常
if ($throwable instanceof MyException) {
// 格式化输出
$data = json_encode([
'code' => $throwable->getCode(),
'msg' => $throwable->getMessage(),
'data' => $throwable->data,
], JSON_UNESCAPED_UNICODE);
// 阻止异常冒泡
$this->stopPropagation();
return $response->withStatus(200)->withBody(new SwooleStream($data));
}
// 交给下一个异常处理器
return $response;
}
/**
* 判断该异常处理器是否要对该异常进行处理
*/
public function isValid(Throwable $throwable): bool
{
return true;
}
}
然后我们的通用抛出方法
public function returnError(string $msg = '操作失败', int $code = 400, $data = [])
{
throw new MyException($msg, $code, $data);
}
这样在任何地方也可以直接中断运行并返回消息了,不用在Service中return给Controller让控制器做处理了。
当然你也可以建很多个异常类,不同的错误类型通过抛不同的异常类就行了。
但是一把梭更香,在我的世界里面,不是200通过就是400错误。没有其他的错误代码,至于错误原因,我又不做多语言,直接汉语告诉你了!!!!
最后还要去config里面配置一下
位于config/autoload/exceptions.php
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
return [
'handler' => [
'http' => [
\App\Exception\Handler\BaseExceptionHandler::class,
\Hyperf\ExceptionHandler\Handler\WhoopsExceptionHandler::class
],
],
];
我引入了一个whoops异常,就是laravel用的那个漂亮的异常追踪界面
官方文档是这样介绍的,用了一样方式进行引入,结果返回给我的是这样的。。
这是通过ajax去取结果返回长成这样了,没有好看的界面了,我觉得应该是发起请求的request header中的accept的问题。因为直接通过浏览器去访问接口好看的界面又出来了,后面在研究一下吧
