64 lines
1.7 KiB
PHP
64 lines
1.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
final class ApiExceptionResponse
|
|
{
|
|
public static function normalize(Response $response, Request $request): Response
|
|
{
|
|
if (! $request->is('api/*')) {
|
|
return $response;
|
|
}
|
|
|
|
$status = $response->getStatusCode();
|
|
$payload = self::payload($response);
|
|
|
|
if (($payload['success'] ?? null) === false && array_key_exists('message', $payload)) {
|
|
return $response;
|
|
}
|
|
|
|
$errors = [];
|
|
if ($status === 422 && isset($payload['errors']) && is_array($payload['errors'])) {
|
|
$errors = $payload['errors'];
|
|
}
|
|
|
|
$fallback = is_string($payload['message'] ?? null) ? $payload['message'] : '';
|
|
|
|
return ApiResponse::failure(self::messageForStatus($status, $fallback), $errors, $status);
|
|
}
|
|
|
|
public static function messageForStatus(int $status, string $fallback): string
|
|
{
|
|
return match ($status) {
|
|
401 => '未认证',
|
|
403 => '无权访问',
|
|
404 => '资源不存在',
|
|
405 => '方法不允许',
|
|
419 => '页面已过期',
|
|
422 => '参数错误',
|
|
429 => '请求过于频繁',
|
|
default => $status >= 500 ? '操作失败' : ($fallback !== '' ? $fallback : '操作失败'),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
private static function payload(Response $response): array
|
|
{
|
|
if (! $response instanceof JsonResponse) {
|
|
return [];
|
|
}
|
|
|
|
$data = $response->getData(true);
|
|
|
|
return is_array($data) ? $data : [];
|
|
}
|
|
}
|