71 lines
2.1 KiB
PHP
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);
|
|
}
|
|
}
|