Skip to content

feat: add HTTP 429 rate limit retry support#83

Merged
mikeh-lago merged 10 commits intomainfrom
feat/rate-limit-retry
Apr 13, 2026
Merged

feat: add HTTP 429 rate limit retry support#83
mikeh-lago merged 10 commits intomainfrom
feat/rate-limit-retry

Conversation

@mikeh-lago
Copy link
Copy Markdown
Contributor

Summary

  • Add LagoRateLimitError class and parseRateLimitHeaders utility
  • Add createRateLimitFetch wrapper with configurable retry and backoff
  • Integrates with Client via rateLimitRetry config option

Test plan

  • Tests for error class, header parsing, retry logic, max retries, non-429 passthrough
  • All existing tests pass

🤖 Generated with Claude Code

Lago Developer and others added 10 commits April 10, 2026 10:19
- Add LagoRateLimitError class for 429 responses
- Parse x-ratelimit-* headers from responses
- Implement automatic retry on 429 with configurable max retries
- Support header-based reset timing and exponential backoff
- Create fetch wrapper to intercept and handle rate limiting
- Add LagoClientConfig with rateLimitRetry options
- Include comprehensive tests for all rate limiting features
- Add RATE_LIMITING.md documentation
- Add rate_limiting_example.ts with usage patterns
- Maintain backward compatibility with existing API
- Do not modify generated OpenAPI code
mock_fetch library's URLPattern is incompatible with current Deno.
Replace with a lightweight createMockFetch helper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ed docs

- Fix getWaitTime to actually fall back to exponential backoff
  (1s, 2s, 4s...) when x-ratelimit-reset header is missing.
  Previously always used error.retryAfter which defaulted to 60s,
  meaning every retry without a header waited a full minute.
- Change missing-header default from 60 to -1 so the backoff path
  is triggered correctly.
- Remove RateLimitRetryHandler class (rate_limit_retry.ts) — both
  branches of handleResponse() threw unconditionally, making the
  retryOnRateLimit flag a no-op. The class was never used by
  createRateLimitFetch. Remove its export from mod.ts.
- Remove RATE_LIMITING.md (394 lines) and examples/rate_limiting_example.ts
  (305 lines of commented-out code).
- Add test verifying exponential backoff triggers ~1s wait (not 60s)
  when reset header is absent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Local Deno generated lockfile v5 which is unsupported by CI's
Deno 1.46.3. Removing so CI can regenerate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents excessively long waits when the server returns a large
x-ratelimit-reset value. Applies to both header-based and
exponential backoff delays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@vincent-pochet vincent-pochet left a comment

Choose a reason for hiding this comment

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

🚀

@mikeh-lago mikeh-lago merged commit d69e59c into main Apr 13, 2026
6 checks passed
@mikeh-lago mikeh-lago deleted the feat/rate-limit-retry branch April 13, 2026 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants