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
  • Created a RateLimitExceededException to handle 429 across all AI platforms
  • Unified the handling of rate limit responses with platform-specific retry information
  • Used platform-specific header extraction for each provider:
    • Anthropic: Standard retry-after HTTP header (seconds)
    • Gemini: No retry information provided
    • OpenAI: Custom headers x-ratelimit-reset-requests and x-ratelimit-reset-tokens

Copy link
Contributor

@VincentLanglet VincentLanglet left a comment

Choose a reason for hiding this comment

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

Could be nice to document ResultConverterInterface::convert that it can throws exception then.

With something like

    /**
     * @param array<string, mixed> $options
     *
     * @throws RateExceededException when rate limit exceeeded
     * @throws RuntimeException when another error occured
     */
    public function convert(RawResultInterface $result, array $options = []): ResultInterface;

@floranpagliai floranpagliai marked this pull request as ready for review September 12, 2025 10:37
@carsonbot carsonbot added Platform Issues & PRs about the AI Platform component Status: Needs Review labels Sep 12, 2025
@OskarStark
Copy link
Contributor

lets call it RateLimitExceededException

@floranpagliai floranpagliai changed the title [Platform] Expose API errors for better Developer Experience [Platform] Implement RateLimitExceededException handling across AI platforms Sep 12, 2025
@floranpagliai
Copy link
Contributor Author

@OskarStark installation of PHPStan is flakky, don't know if you can launch again the CI.

@OskarStark OskarStark changed the title [Platform] Implement RateLimitExceededException handling across AI platforms [Platform] Implement RateLimitExceededException handling across AI platforms Sep 12, 2025
@floranpagliai
Copy link
Contributor Author

Could be nice to document ResultConverterInterface::convert that it can throws exception then.

With something like

    /**
     * @param array<string, mixed> $options
     *
     * @throws RateExceededException when rate limit exceeeded
     * @throws RuntimeException when another error occured
     */
    public function convert(RawResultInterface $result, array $options = []): ResultInterface;

Agreed, will include it in a try to have a higher level ResultConverter.

@chr-hertel chr-hertel added the Hackathon 2025 This issue or pull request was part of the Symfony AI Hackathon 2025 label Sep 12, 2025
/**
* @author Floran Pagliai <floran.pagliai@gmail.com>
*/
final class RateLimitExceededException extends \RuntimeException implements ExceptionInterface
Copy link
Member

Choose a reason for hiding this comment

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

don't see this as a RuntimeException tho

Suggested change
final class RateLimitExceededException extends \RuntimeException implements ExceptionInterface
final class RateLimitExceededException extends \InvalidArgumentException implements ExceptionInterface

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I get your point, but I’m not sure \InvalidArgumentException is the best fit here. A rate limit being exceeded isn’t really about invalid input, it’s more of an external condition depending of usage. That’s why I went with \RuntimeException.

Another option could be to extend directly from a generic \Exception or define a dedicated base exception for API-related errors ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe my point of view, but i consider

  • a LogicException being an exception which should never happen unless bad code is written, and the dev should fix his code. (Bad param, bad call, case which shouldn't exist, etc)
  • a RuntimeException being an exception which is not avoidable and might occurs under some circonstances

Here, it seems to be a Runtime one to me.

Copy link
Contributor

Choose a reason for hiding this comment

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

But what about extending directly the symfony/ai RuntimeException
https://github.com/symfony/ai/blob/main/src/platform/src/Exception/RuntimeException.php

rather than extending \RuntimeException and implementing the ExceptionInterface ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@chr-hertel
Copy link
Member

Thank you @floranpagliai.

@chr-hertel chr-hertel merged commit 7c1652c into symfony:main Sep 13, 2025
11 of 12 checks passed
OskarStark added a commit that referenced this pull request Oct 2, 2025
…ntLanglet)

This PR was merged into the main branch.

Discussion
----------

[Agent][Platform] Improve `ResultConverter`PHPDoc

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Docs?         | yes
| Issues        | Fix #...
| License       | MIT

Since #538 exceptions thrown by `ResultConverterInterface::convert` are more useful and should be documented.
I personally use them when doing `Agent::call`, and they are accessible because
Agent::call use `getResult` which use `await` which use `convert`.

I added some basic documentation about them then.

Commits
-------

10ce6b3 Improve ResultConverter phpdoc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Hackathon 2025 This issue or pull request was part of the Symfony AI Hackathon 2025 Platform Issues & PRs about the AI Platform component Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants