2f3268c0b7
Move all provider-related classes, enums, interface and trait into App\Service\Provider; move SvgRenderer into App\Service\Renderer. ContributionAggregator stays at the Service root as the orchestrator. Test namespaces and use statements updated to match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.3 KiB
PHP
64 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service\Provider;
|
|
|
|
use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface;
|
|
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
|
|
trait ProbeTrait
|
|
{
|
|
public function probe(): ProviderStatus
|
|
{
|
|
if (!$this->isConfigured()) {
|
|
return new ProviderStatus($this->getName(), ProviderStatusType::NotConfigured);
|
|
}
|
|
|
|
try {
|
|
$this->ping();
|
|
|
|
return new ProviderStatus($this->getName(), ProviderStatusType::Ok);
|
|
} catch (\Throwable $e) {
|
|
return $this->statusFromException($e);
|
|
}
|
|
}
|
|
|
|
private function statusFromException(\Throwable $e): ProviderStatus
|
|
{
|
|
[$error, $message] = $this->classifyException($e);
|
|
|
|
return new ProviderStatus($this->getName(), ProviderStatusType::Error, $error, $message);
|
|
}
|
|
|
|
/** @return array{ProviderErrorCode, string} */
|
|
private function classifyException(\Throwable $e): array
|
|
{
|
|
if ($e instanceof TransportExceptionInterface) {
|
|
return [ProviderErrorCode::UrlUnreachable, 'Could not reach the server: ' . $e->getMessage()];
|
|
}
|
|
|
|
if ($e instanceof HttpExceptionInterface) {
|
|
$code = $e->getResponse()->getStatusCode();
|
|
|
|
return match (true) {
|
|
$code === 401 => [ProviderErrorCode::AuthFailed, 'Invalid or expired token — verify your credentials'],
|
|
$code === 403 => [ProviderErrorCode::AuthFailed, 'Access denied — token lacks the required scopes'],
|
|
$code === 404 => [ProviderErrorCode::UrlUnreachable, 'Endpoint not found — check the configured URL'],
|
|
default => [ProviderErrorCode::Unknown, "HTTP {$code}: " . $e->getMessage()],
|
|
};
|
|
}
|
|
|
|
$msg = $e->getMessage();
|
|
$lower = strtolower($msg);
|
|
$error = match (true) {
|
|
str_contains($msg, 'not found') || str_contains($msg, 'Could not resolve') => ProviderErrorCode::UserNotFound,
|
|
str_contains($msg, 'GraphQL error')
|
|
&& (str_contains($lower, 'unauthorized') || str_contains($lower, 'bad credentials')) => ProviderErrorCode::AuthFailed,
|
|
default => ProviderErrorCode::Unknown,
|
|
};
|
|
|
|
return [$error, $msg];
|
|
}
|
|
}
|