diff --git a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php index c973b1c0e..8f9acd63a 100644 --- a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php +++ b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php @@ -12,6 +12,7 @@ namespace Symfony\AI\Platform\Bridge\OpenAi\Gpt; use Symfony\AI\Platform\Bridge\OpenAi\Gpt; +use Symfony\AI\Platform\Exception\AuthenticationException; use Symfony\AI\Platform\Exception\ContentFilterException; use Symfony\AI\Platform\Exception\RuntimeException; use Symfony\AI\Platform\Model; @@ -42,6 +43,13 @@ public function supports(Model $model): bool public function convert(RawResultInterface|RawHttpResult $result, array $options = []): ResultInterface { + $response = $result->getObject(); + + if (401 === $response->getStatusCode()) { + $errorMessage = json_decode($response->getContent(false), true)['error']['message']; + throw new AuthenticationException($errorMessage); + } + if ($options['stream'] ?? false) { return new StreamResult($this->convertStream($result->getObject())); } diff --git a/src/platform/src/Exception/AuthenticationException.php b/src/platform/src/Exception/AuthenticationException.php new file mode 100644 index 000000000..4fe78b41f --- /dev/null +++ b/src/platform/src/Exception/AuthenticationException.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Exception; + +/** + * Exception thrown when API authentication fails. + * + * @author Vitalii Kyktov + * @author Dmytro Liashko + */ +class AuthenticationException extends RuntimeException +{ +} diff --git a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php b/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php index 032769f4f..447397b10 100644 --- a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php +++ b/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php @@ -16,6 +16,7 @@ use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter; +use Symfony\AI\Platform\Exception\AuthenticationException; use Symfony\AI\Platform\Exception\ContentFilterException; use Symfony\AI\Platform\Exception\RuntimeException; use Symfony\AI\Platform\Result\ChoiceResult; @@ -155,6 +156,23 @@ public function getResponse(): ResponseInterface $converter->convert(new RawHttpResult($httpResponse)); } + public function testThrowsAuthenticationExceptionOnInvalidApiKey() + { + $converter = new ResultConverter(); + $httpResponse = self::createMock(ResponseInterface::class); + $httpResponse->method('getStatusCode')->willReturn(401); + $httpResponse->method('getContent')->willReturn(json_encode([ + 'error' => [ + 'message' => 'Invalid API key provided: sk-invalid', + ], + ])); + + $this->expectException(AuthenticationException::class); + $this->expectExceptionMessage('Invalid API key provided: sk-invalid'); + + $converter->convert(new RawHttpResult($httpResponse)); + } + public function testThrowsExceptionWhenNoChoices() { $converter = new ResultConverter();