Files
alfa-bank-sdk/src/Traits/HasAlfaErrorHandling.php
2026-04-07 18:47:53 +03:00

71 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Apoloz\AlfaBank\Traits;
use Apoloz\AlfaBank\Exceptions\AlfaBankException;
use Saloon\Http\Response;
use Throwable;
trait HasAlfaErrorHandling
{
/**
* Determine if the request has failed.
*/
public function hasRequestFailed(Response $response): ?bool
{
if ($response->status() >= 400) {
return true;
}
$contentType = $response->header('Content-Type') ?? '';
if (str_contains($contentType, 'application/json')) {
$data = $response->json();
if (isset($data['error']) || (isset($data['ErrorCode']) && (string) $data['ErrorCode'] !== '0')) {
return true;
}
}
return false;
}
/**
* Get the custom exception for the failed request.
*/
public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable
{
$requestId = $response->header('X-Request-ID') ?? 'Unknown';
$errorCode = 'UNKNOWN';
$errorDescription = 'No description';
$contentType = $response->header('Content-Type') ?? '';
if (str_contains($contentType, 'application/json')) {
$data = $response->json();
$errorCode = $data['error'] ?? $data['ErrorCode'] ?? 'HTTP_' . $response->status();
$rawDescription = $data['error_description'] ?? $data['message'] ?? 'Request failed';
$errorDescription = $this->decodeBankMessage($rawDescription);
} else {
$errorCode = 'HTTP_' . $response->status();
$errorDescription = 'Request failed with status ' . $response->status();
}
return new AlfaBankException(
$response,
(string) $errorCode,
"({$requestId}) {$errorDescription}"
);
}
private function decodeBankMessage(string $message): string
{
$decoded = preg_replace_callback(
'/%u([0-9A-Fa-f]{4})/',
fn ($m) => mb_convert_encoding(pack('H*', $m[1]), 'UTF-8', 'UCS-2BE'),
$message
);
return urldecode($decoded);
}
}