Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/sdk-php. php sdk for openstatus www.openstatus.dev
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155<?php
declare(strict_types=1);
namespace Openstatus\Sdk\Internal;
use Openstatus\Sdk\Exception\AuthenticationException;use Openstatus\Sdk\Exception\ConnectErrorDetail;use Openstatus\Sdk\Exception\InvalidArgumentException;use Openstatus\Sdk\Exception\NotFoundException;use Openstatus\Sdk\Exception\OpenstatusException;use Openstatus\Sdk\Exception\PermissionDeniedException;use Openstatus\Sdk\Exception\RateLimitException;use Openstatus\Sdk\Exception\ServiceUnavailableException;use Psr\Http\Message\ResponseInterface;
final class ConnectErrorMapper{ /** * @return never * @throws OpenstatusException */ public static function rethrow(ResponseInterface $response): void { $httpStatus = $response->getStatusCode(); $rawBody = (string) $response->getBody();
$envelope = self::parseEnvelope($rawBody); if ($envelope === null) { $reason = $response->getReasonPhrase(); $message = sprintf( 'HTTP %d%s (no Connect error envelope)', $httpStatus, $reason !== '' ? ': ' . $reason : '', );
throw new ServiceUnavailableException( message: $message, connectCode: 'unavailable', httpStatus: $httpStatus, details: [], rawBody: $rawBody, ); }
[$code, $message, $details] = $envelope;
throw match ($code) { 'unauthenticated' => new AuthenticationException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), 'not_found' => new NotFoundException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), 'invalid_argument' => new InvalidArgumentException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), 'permission_denied' => new PermissionDeniedException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), 'resource_exhausted' => new RateLimitException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), 'unavailable' => new ServiceUnavailableException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), default => new OpenstatusException( message: $message, connectCode: $code, httpStatus: $httpStatus, details: $details, rawBody: $rawBody, ), }; }
/** * @return array{0: string, 1: string, 2: list<ConnectErrorDetail>}|null */ private static function parseEnvelope(string $rawBody): ?array { if ($rawBody === '') { return null; } try { $decoded = json_decode($rawBody, associative: true, flags: JSON_THROW_ON_ERROR); } catch (\JsonException) { return null; } if (!is_array($decoded)) { return null; } $code = $decoded['code'] ?? null; $message = $decoded['message'] ?? null; if (!is_string($code) || !is_string($message)) { return null; }
$details = self::parseDetails($decoded['details'] ?? null);
return [$code, $message, $details]; }
/** * @return list<ConnectErrorDetail> */ private static function parseDetails(mixed $raw): array { if (!is_array($raw)) { return []; } $details = []; foreach ($raw as $item) { if (!is_array($item)) { continue; } $type = $item['type'] ?? null; $value = $item['value'] ?? null; $debug = $item['debug'] ?? null; if (is_string($type) && is_string($value)) { $details[] = new ConnectErrorDetail( type: $type, value: $value, debug: is_string($debug) ? $debug : null, ); } } return $details; }}