mirror of
https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git
synced 2025-12-26 02:17:48 +08:00
71 lines
2.2 KiB
PHP
71 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Exception\Handler;
|
|
|
|
|
|
use App\Lib\Return\AdminReturn;
|
|
use App\Lib\Return\ApiReturn;
|
|
use Hyperf\ExceptionHandler\ExceptionHandler;
|
|
use Hyperf\HttpMessage\Stream\SwooleStream;
|
|
use Hyperf\HttpServer\Request;
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
use Psr\Container\ContainerInterface;
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|
use Psr\Http\Message\MessageInterface;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
use Throwable;
|
|
|
|
abstract class BaseErrExceptionHandler extends ExceptionHandler
|
|
{
|
|
public function __construct(
|
|
private readonly Request $request,
|
|
private readonly ContainerInterface $container,
|
|
) {}
|
|
|
|
/**
|
|
* @param Throwable $e
|
|
* @param ResponseInterface $response
|
|
* @return MessageInterface|ResponseInterface
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
protected function handlerResponse(
|
|
Throwable $e,
|
|
ResponseInterface $response
|
|
): MessageInterface|ResponseInterface
|
|
{
|
|
// 从注解获取响应格式(优先于路径解析)
|
|
$format = $this->request->getAttribute('response_format') ?? $this->repairResponseFormatByPath();
|
|
|
|
// 动态选择策略
|
|
$returnClass = match ($format) {
|
|
'admin', 'common' => AdminReturn::class,
|
|
'api' => ApiReturn::class,
|
|
default => null,
|
|
};
|
|
if (!$returnClass) return $response;
|
|
|
|
/**
|
|
* @var AdminReturn|ApiReturn $returnObj
|
|
*/
|
|
$returnObj = $this->container->get($returnClass);
|
|
$result = $returnObj->error($e->getMessage(), $e->getCode(), $e?->getData() ?? []);
|
|
$this->stopPropagation();
|
|
return $response->withHeader("Content-Type", "application/json")
|
|
->withStatus(200)
|
|
->withBody(new SwooleStream(json_encode($result, JSON_UNESCAPED_UNICODE)));
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
private function repairResponseFormatByPath(): string
|
|
{
|
|
// 兜底逻辑:根据路径前缀推断
|
|
return match (explode('/', $this->request->path())[0] ?? '') {
|
|
'admin', 'common' => 'admin',
|
|
'api' => 'api',
|
|
default => 'default',
|
|
};
|
|
}
|
|
} |