Skip to content

Conversation

floranpagliai
Copy link
Contributor

@floranpagliai floranpagliai commented Sep 12, 2025

Q A
Bug fix? no
New feature? no
Docs? no
Issues #528
License MIT

I've created a simple trait to standardize HTTP response status code handling across different platform bridges. Currently, each bridge implements its own error handling, leading to inconsistent exception behavior and code duplication.

The ResultConverterStatusExceptionTrait

This trait provides:

  • Common method validateStatusCode() for checking HTTP response status codes
  • Standardized handling of 401, 429, and other error codes
  • Extension points for platform-specific headers (like OpenAI's x-ratelimit headers)
  • Consistent error message extraction from responses

Need feedback:

  • Is this trait approach the right way to standardize error handling? Or would you prefer a different pattern?

  • Should the trait be more or less opinionated about which status codes to handle?

  • Are there other common error patterns that should be included?

  • Is the naming appropriate and in line with conventions?

    Depending on feedback, I plan to implement this in all ResultConverters to standardize error handling across platforms.

@welcoMattic welcoMattic added Platform Issues & PRs about the AI Platform component Feature New feature Hackathon 2025 This issue or pull request was part of the Symfony AI Hackathon 2025 labels Sep 12, 2025
Copy link
Member

@chr-hertel chr-hertel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a service instead of a trait.

edit: not convinced that this is the right place tho anyways tbh

@chr-hertel
Copy link
Member

What do you think about handling generic http status code in Symfony\AI\Platform\Result\RawHttpResult::getData?

@floranpagliai
Copy link
Contributor Author

I agree that a service approach would be better. My concern is balancing common error handling with platform-specific flexibility.

What about transforming RawHttpResult into an abstract class with common error handling that platform bridges can extend?

  abstract class AbstractRawHttpResult implements RawResultInterface 
  {
      public function getData(): array 
      {
          $this->validateResponse($this->response);
          return $this->response->toArray(false);
      }

      protected function validateResponse(ResponseInterface $response): void
      {
          $statusCode = $response->getStatusCode();

          if (200 <= $statusCode && 300 > $statusCode) {
              return; 
          }
          switch ($statusCode) {
              case 401:
                  $this->handleAuthenticationError($response);
                  break;
              case 429:
                  $this->handleRateLimitExceeded($response);
                  break;
              default:
                  $this->handleGenericError($response);
                  break;
          }
      }

      protected function handleRateLimitExceeded(ResponseInterface $response): void 
      {

          $retryAfter = $this->extractRetryAfterValue($response);
          throw new RateLimitExceededException($retryAfter);
      }

      protected function extractRetryAfterValue(ResponseInterface $response): ?float
      {
          // Standard header extraction
          $headers = $response->getHeaders(false);

          if (isset($headers['retry-after'][0])) {
              return (float) $headers['retry-after'][0];
          }

          return null;
      }
  }

  class OpenAiRawHttpResult extends AbstractRawHttpResult 
  {
      protected function extractRetryAfterValue(ResponseInterface $response): ?float 
      {
          // OpenAI-specific implementation with custom headers
          $headers = $response->getHeaders(false);
          $resetTime = null;

          if (isset($headers['x-ratelimit-reset-requests'][0])) {
              $resetTime = $this->parseResetTime($headers['x-ratelimit-reset-requests'][0]);
          } elseif (isset($headers['x-ratelimit-reset-tokens'][0])) {
              $resetTime = $this->parseResetTime($headers['x-ratelimit-reset-tokens'][0]);
          }

          return resetTime;
      }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature Hackathon 2025 This issue or pull request was part of the Symfony AI Hackathon 2025 Platform Issues & PRs about the AI Platform component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants