Conversation
A plugin auto retry base on `Retry-After` response header. Fixes #1181
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🪛 LanguageToolapps/content/docs/plugins/retry-after.md[uncategorized] ~8-~8: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL) ⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
🔇 Additional comments (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @unnoq, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant enhancement to the client-side request handling by adding a new Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new RetryAfterPlugin for the client, which is a valuable addition for automatically handling rate-limited requests. The implementation is robust, well-tested, and includes comprehensive documentation. My review includes a minor correction for a typo in the documentation and a more significant point about a new dependency introduced in the ratelimit package, which could be an architectural concern.
There was a problem hiding this comment.
Pull Request Overview
This PR adds a new RetryAfterPlugin for automatic client-side request retries based on server Retry-After headers, commonly used for rate limiting and temporary service unavailability scenarios.
- Implements a configurable retry plugin with support for custom conditions, maximum attempts, and timeout settings
- Updates the ratelimit handler to use error status constants instead of magic numbers
- Includes comprehensive test coverage and documentation
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/client/src/plugins/retry-after.ts | New plugin implementation with retry logic based on Retry-After headers |
| packages/client/src/plugins/retry-after.test.ts | Comprehensive test suite covering core behavior, parsing, limits, and signal handling |
| packages/client/src/plugins/index.ts | Export statement for new plugin |
| packages/ratelimit/src/handler-plugin.ts | Replace magic number 429 with constant from COMMON_ORPC_ERROR_DEFS |
| apps/content/docs/plugins/retry-after.md | Documentation for the new plugin |
| apps/content/docs/helpers/ratelimit.md | Cross-reference to retry-after plugin |
| apps/content/.vitepress/config.ts | Navigation entry for plugin documentation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
More templates
@orpc/ai-sdk
@orpc/arktype
@orpc/client
@orpc/contract
@orpc/experimental-durable-iterator
@orpc/hey-api
@orpc/interop
@orpc/json-schema
@orpc/nest
@orpc/openapi
@orpc/openapi-client
@orpc/otel
@orpc/experimental-publisher
@orpc/experimental-ratelimit
@orpc/react
@orpc/react-query
@orpc/experimental-react-swr
@orpc/server
@orpc/shared
@orpc/solid-query
@orpc/standard-server
@orpc/standard-server-aws-lambda
@orpc/standard-server-fastify
@orpc/standard-server-fetch
@orpc/standard-server-node
@orpc/standard-server-peer
@orpc/svelte-query
@orpc/tanstack-query
@orpc/trpc
@orpc/valibot
@orpc/vue-colada
@orpc/vue-query
@orpc/zod
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/content/.vitepress/config.ts(1 hunks)apps/content/docs/helpers/ratelimit.md(1 hunks)apps/content/docs/plugins/retry-after.md(1 hunks)packages/client/src/plugins/index.ts(1 hunks)packages/client/src/plugins/retry-after.test.ts(1 hunks)packages/client/src/plugins/retry-after.ts(1 hunks)packages/ratelimit/src/handler-plugin.ts(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/client/src/plugins/retry-after.test.ts (3)
packages/standard-server/src/types.ts (1)
StandardLazyResponse(43-49)packages/client/src/adapters/standard/link.ts (1)
StandardLink(24-109)packages/client/src/plugins/retry-after.ts (1)
RetryAfterPlugin(47-147)
packages/client/src/plugins/retry-after.ts (6)
packages/shared/src/value.ts (1)
Value(1-1)packages/standard-server/src/types.ts (1)
StandardLazyResponse(43-49)packages/client/src/adapters/standard/link.ts (2)
StandardLinkClientInterceptorOptions(14-16)StandardLinkOptions(18-22)packages/client/src/adapters/standard/plugin.ts (1)
StandardLinkPlugin(4-7)packages/client/src/error.ts (1)
COMMON_ORPC_ERROR_DEFS(5-83)packages/standard-server/src/utils.ts (1)
flattenHeader(51-61)
packages/ratelimit/src/handler-plugin.ts (1)
packages/client/src/error.ts (1)
COMMON_ORPC_ERROR_DEFS(5-83)
🪛 LanguageTool
apps/content/docs/plugins/retry-after.md
[uncategorized] ~8-~8: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...his is particularly useful for handling rate limiting and temporary server unavailability. #...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Upload results
- GitHub Check: publish-commit
- GitHub Check: lint
- GitHub Check: test
🔇 Additional comments (16)
packages/ratelimit/src/handler-plugin.ts (1)
4-4: LGTM! Good refactor to use centralized error definitions.Replacing the hardcoded
429withCOMMON_ORPC_ERROR_DEFS.TOO_MANY_REQUESTS.statusimproves maintainability and aligns with the new RetryAfter plugin's approach.Also applies to: 52-52
packages/client/src/plugins/index.ts (1)
4-4: LGTM! Export follows existing patterns.The new export is consistent with other plugin exports in this barrel file.
apps/content/docs/helpers/ratelimit.md (1)
227-229: LGTM! Good cross-reference to related plugin.The info block effectively guides users to the complementary Retry After Plugin, improving discoverability of synergistic features.
apps/content/.vitepress/config.ts (1)
152-152: LGTM! Navigation entry properly configured.The Retry After plugin entry is correctly placed in the Plugins section with the appropriate link path.
apps/content/docs/plugins/retry-after.md (2)
12-28: LGTM! Clear and comprehensive example.The usage example demonstrates all key features of the plugin with helpful inline comments.
30-36: LGTM! Options are well-documented.All options are clearly described with their default values and expected behavior.
packages/client/src/plugins/retry-after.test.ts (5)
28-83: LGTM! Core behavior tests are thorough.The tests effectively cover both successful retry scenarios and edge cases where retries should not occur (missing header, non-retryable status codes).
85-145: LGTM! Comprehensive parsing validation.The tests cover various Retry-After formats (numeric seconds, HTTP dates, whitespace handling) and properly validate that invalid values prevent retries.
147-182: LGTM! MaxAttempts logic thoroughly tested.The tests cover default, static, and dynamic maxAttempts configurations, including verification that dynamic functions are invoked with the correct arguments.
184-261: LGTM! Timeout and condition logic well-tested.The tests validate static and dynamic timeout configurations, as well as custom condition functions, including proper argument passing.
263-306: LGTM! Signal handling is properly tested.The tests validate both mid-delay abort scenarios and pre-aborted signals, ensuring the plugin respects cancellation requests.
packages/client/src/plugins/retry-after.ts (5)
9-39: LGTM! Well-designed options interface.The use of
Value<T, TArgs>allows both static and dynamic (function-based) configuration, providing excellent flexibility. Documentation clearly specifies defaults.
47-63: LGTM! Constructor properly initializes defaults.The constructor correctly sets default values matching the documentation, and uses centralized error definitions for status code comparisons.
65-103: LGTM! Retry interceptor logic is solid.The retry loop correctly:
- Evaluates the retry condition after each response
- Respects maxAttempts boundaries
- Enforces timeout constraints
- Handles signal cancellation gracefully
- Returns immediately when retry criteria aren't met
105-123: LGTM! Robust Retry-After header parsing.The method correctly handles both numeric (seconds) and HTTP-date formats per the HTTP specification, with proper edge case handling for negative values and invalid inputs.
125-146: LGTM! Delay implementation handles cancellation correctly.The promise-based delay properly:
- Checks for pre-aborted signals
- Responds to mid-delay cancellation
- Cleans up event listeners in both abort and completion paths
- Uses
once: truefor automatic cleanup
A plugin auto retry base on
Retry-Afterresponse header.Fixes #1181
Summary by CodeRabbit
New Features
Documentation
Tests
Bug Fixes