3.5 异常处理

Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处理的异常的话,都会导致对应的 Worker 进程 被中断退出,这对服务而言也是不能接受的,捕获异常并输出合理的报错内容给客户端也是更加友好的。
我们可以通过对各个 server 定义不同的 异常处理器(ExceptionHandler),一旦业务流程存在没有捕获的异常,都会被传递到已注册的 异常处理器(ExceptionHandler) 去处理。

1. 创建处理某个异常的类

touch app/Exception/Handler/ResourceExceptionHandler.php
<?php
namespace App\Exception\Handler;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;

class ResourceExceptionHandler extends ExceptionHandler
{
    /**
     * @var StdoutLoggerInterface
     */
    protected $logger;

    /**
     * @Inject()
     * @var \Hyperf\HttpServer\Contract\ResponseInterface
     */
    protected $response;

    public function __construct(StdoutLoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        // 不再往下传递异常错误
        $this->stopPropagation();
        // 将错误的信息返回出去
        return $this->response->json([
            'error' => 500,
            'data' => []
        ]);
    }

    /**
     * 确定当前的异常处理程序是否应该处理异常。
     */
    public function isValid(Throwable $throwable): bool
    {
        return $throwable instanceof \App\Exception\ResourceException;
    }
}

2. 创建异常类

touch app/Exception/ResourceException.php
<?php
namespace App\Exception;

class ResourceException extends \RuntimeException
{

}

3. 定义异常:在config/autoload/exceptions.php中定义

<?php

return [
    'handler' => [
        'http' => [
            Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
            App\Exception\Handler\AppExceptionHandler::class,
            // 注册之前定义好的错误处理类
            App\Exception\Handler\ResourceExceptionHandler::class
        ],
    ],
];

4. 使用

<?php
namespace App\Controller;

use App\Exception\ResourceException;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;

/**
 * @AutoController()
 */
class IndexController extends AbstractController
{
    public function index()
    {
        throw new ResourceException();
    }
}
文档更新时间: 2021-09-24 16:12   作者:赵豪