Jerry's WIKIJerry's WIKI
概述
  • 🐞 web使用
  • 📐 常用组件
  • 💡 使用技巧
  • 🎱 规范相关
  • 🖥 工作流
  • 🛠 常用工具
  • 🌐️ 服务器
  • 📦 容器相关
  • ♨️ 编程语言
咖啡屋
  • 简体中文
  • English
GitHub
概述
  • 🐞 web使用
  • 📐 常用组件
  • 💡 使用技巧
  • 🎱 规范相关
  • 🖥 工作流
  • 🛠 常用工具
  • 🌐️ 服务器
  • 📦 容器相关
  • ♨️ 编程语言
咖啡屋
  • 简体中文
  • English
GitHub
  • 📞 事件机制

    • 事件角色和注意事项
    • 代码示例
  • ⏰ 定时任务
  • ⛓ 自定义进程
  • 📝 文件系统
  • 🕓 缓存系统
  • 📩 异步队列

    • 队列使用
    • 注意事项
  • 🚦 信号处理器
  • 📤 GuzzleHttp
  • 📉 限流器
  • ❌ 异常处理器
  • 🖨 日志
  • 📡 命令行
  • 🔁 WebSocket

异常处理器

目录

  • 封装异常处理器
  • 注册异常处理器
  • 封装自定义异常

【注意】

  1. 任何的 HTTP请求 的返回均应该返回标准格式的响应。
  2. 代码异常 和 逻辑异常 都应该捕获和处理,即:均返回 200、401、422、500 状态码,且为统一的 JSON 格式。
  3. worker 进程中的异常配置后,底层框架会自动处理,但是 自定义进程,队列消费进程 中的异常应自己处理。
  4. 三方包的底层异常,也应该封装对应的异常处理器。

所有异常处理器参见: 异常处理器


封装异常处理器

普通异常处理器

<?php

declare(strict_types=1);
namespace App\Exception\Handler;

use AlibabaCloud\Tea\Exception\TeaError;
use App\Constants\SystemCode;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\ResponseInterface;
use Throwable;

/**
 * 阿里云底层包异常捕获.
 * Class AlibabaExceptionHandler.
 */
class AlibabaExceptionHandler extends ExceptionHandler
{
    /**
     * 处理类.
     * @param Throwable $throwable 异常
     * @param ResponseInterface $response 响应接口实现类
     * @return MessageInterface|ResponseInterface 响应接口实现类
     */
    public function handle(Throwable $throwable, ResponseInterface $response): MessageInterface|ResponseInterface
    {
        $this->stopPropagation();

        return $response->withHeader('Content-Type', 'application/json')
            ->withStatus(200)->withBody(new SwooleStream(json_encode([
                'code' => SystemCode::ALIBABA_ERR,
                'msg' => SystemCode::getMessage(SystemCode::ALIBABA_ERR, [$throwable->getMessage()]),
                'status' => false,
                'data' => [],
            ], JSON_UNESCAPED_UNICODE)));
    }

    /**
     * 是否满足处理条件.
     * @param Throwable $throwable 异常
     * @return bool true|false
     */
    public function isValid(Throwable $throwable): bool
    {
        return $throwable instanceof TeaError;
    }
}


全局异常处理器

<?php

declare(strict_types=1);
namespace App\Exception\Handler;

use App\Constants\SystemCode;
use App\Lib\Log\Log;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;

/**
 * 全局兜底异常处理器.
 * Class AppExceptionHandler.
 */
class AppExceptionHandler extends ExceptionHandler
{
    /**
     * 处理类.
     * @param Throwable $throwable 异常
     * @param ResponseInterface $response 响应接口实现类
     * @return ResponseInterface 响应接口实现类
     */
    public function handle(Throwable $throwable, ResponseInterface $response): ResponseInterface
    {
        Log::error(
            sprintf('发生系统异常:%s', $throwable->getMessage()),
            $throwable->getTrace(),
            $throwable->getTraceAsString()
        );

        return $response->withHeader('Content-Type', 'application/json')
            ->withStatus(500)
            ->withBody(new SwooleStream(json_encode([
                'code' => SystemCode::SYSTEM_ERROR,
                'msg' => SystemCode::getMessage(SystemCode::SYSTEM_ERROR),
                'status' => false,
                'data' => [],
            ], JSON_UNESCAPED_UNICODE)));
    }

    /**
     * 是否满足处理条件.
     * @param Throwable $throwable 异常
     * @return bool true|false
     */
    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}

注册异常处理器

【说明】

顺序应该由颗粒度有小到大。


config/autoload/exceptions.php


<?php

declare(strict_types=1);
return [
    'handler' => [
        'http' => [
            // JWT认证失败
            App\Exception\Handler\JwtExceptionHandler::class,
            // 业务逻辑异常
            App\Exception\Handler\BusinessExceptionHandler::class,
            // 验证器类型错误处理
            App\Exception\Handler\ValidationExceptionHandler::class,
            // 文件系统异常捕获
            App\Exception\Handler\FileSystemExceptionHandler::class,
            // 数据库未找到数据异常处理
            App\Exception\Handler\ModelNotFoundExceptionHandler::class,
            // 限流异常处理器
            App\Exception\Handler\RateLimitExceptionHandler::class,
            // redis锁组件异常处理器
            App\Exception\Handler\LockTimeoutExceptionHandler::class,
            // 阿里云包底层异常捕获器
            App\Exception\Handler\AlibabaExceptionHandler::class,
            // phpoffice 包异常捕获
            App\Exception\Handler\OfficeExceptionHandler::class,
            // PHPSeclib 包异常捕获
            App\Exception\Handler\PHPSeclibExceptionHandler::class,
            // 全局(框架)异常处理
            App\Exception\Handler\AppExceptionHandler::class,
            // 全局HTTP异常处理
            Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
        ],
    ],
];

封装自定义异常

一般用于自己业务抛出的异常。

<?php

declare(strict_types=1);
namespace App\Exception;

use App\Constants\ErrorCode;
use Hyperf\Server\Exception\ServerException;
use Throwable;

class BusinessException extends ServerException
{
    public function __construct(int $code = 0, string $message = null, Throwable $previous = null)
    {
        if (is_null($message)) {
            $message = ErrorCode::getMessage($code);
        }

        parent::__construct($message, $code, $previous);
    }
}
编辑此页面
更新时间:
贡献者: 田朝帆
Prev
限流器
Next
日志