Skip to content

fix(integration-discord): handle cloudflare 429#335

Merged
gvieira18 merged 3 commits into
4.xfrom
fix/purge-invites-cloudflare-429
Jun 19, 2026
Merged

fix(integration-discord): handle cloudflare 429#335
gvieira18 merged 3 commits into
4.xfrom
fix/purge-invites-cloudflare-429

Conversation

@gvieira18

Copy link
Copy Markdown
Member

Summary

  • Parse Retry-After from HTTP header when Cloudflare returns a 429 with non-JSON body (error code: 1015), fixing JsonException: Syntax error
  • Abort immediately on Cloudflare IP bans (Retry-After > 60s) instead of wasting retries against a ~22-hour ban
  • Use Arr::get for safe JSON body parsing

Test plan

  • Cloudflare 429 with short Retry-After header: retries and succeeds
  • Cloudflare IP ban with large Retry-After header: aborts immediately, no sleep
  • All 11 tests passing, four checks clean

Parse Retry-After from HTTP header when Discord
returns a Cloudflare 429 with non-JSON body.
Abort immediately on IP bans (retry-after > 60s).
@gvieira18 gvieira18 requested a review from a team June 17, 2026 23:10
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@gvieira18, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 18 minutes and 49 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro

Run ID: f6e15b6a-f576-480f-b4ab-2d01a8c0ac2d

📥 Commits

Reviewing files that changed from the base of the PR and between 02e8673 and 1865409.

📒 Files selected for processing (3)
  • app-modules/integration-discord/src/Sync/Actions/PurgeUnusedInvitesAction.php
  • app-modules/integration-discord/src/Sync/Exceptions/CloudflareIpBanException.php
  • app-modules/integration-discord/tests/Unit/Sync/PurgeUnusedInvitesActionTest.php
📝 Walkthrough

Walkthrough

PurgeUnusedInvitesAction adds an Illuminate\Support\Arr import and a new private parseRetryAfter(Response $response): float helper. This helper reads retry_after from the JSON body via Arr::get, falls back to X-RateLimit-Reset-After or the numeric Retry-After header, and defaults to 1.0. The existing inline 429 handling in deleteInvite() is replaced: if parseRetryAfter() returns a value exceeding 60 seconds, a RuntimeException is thrown immediately; otherwise, jittered backoff continues while attempts remain, after which a RuntimeException with status and body is thrown. Three unit tests are added covering the X-RateLimit-Reset-After header fallback path, the short-Retry-After retry-and-succeed path, and the large-Retry-After immediate-abort path.

Possibly related PRs

  • he4rt/heartdevs.com#333: Extends PurgeUnusedInvitesAction's DeleteInvite HTTP 429/rate-limit retry logic in the Discord integration.
  • he4rt/heartdevs.com#334: Modifies the same PurgeUnusedInvitesAction HTTP 429 retry logic and retry_after parsing in deleteInvite().

Suggested reviewers

  • Clintonrocha98
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly summarizes the main change: handling Cloudflare 429 responses in the Discord integration.
Description check ✅ Passed The description clearly explains the bug fix, implementation details, and test plan, all directly related to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app-modules/integration-discord/src/Sync/Actions/PurgeUnusedInvitesAction.php`:
- Around line 119-120: The RuntimeException thrown when detecting a Cloudflare
IP ban (when retryAfter exceeds 60.0) in the condition at line 119-120 is being
caught by the execute() method at line 74, which allows the purge loop to
continue processing remaining invites instead of stopping the entire operation.
Modify the exception handling in execute() to detect when a RuntimeException
contains "Cloudflare IP ban" in its message and re-throw it without catching it,
so that the IP ban condition propagates up and halts the entire purge operation
rather than continuing with the remaining invites in the loop.

In
`@app-modules/integration-discord/tests/Unit/Sync/PurgeUnusedInvitesActionTest.php`:
- Around line 222-240: The test currently only includes a single invite in the
$invites array, which doesn't exercise the regression where the
PurgeUnusedInvitesAction continues processing subsequent invites after
encountering an IP-ban (429) failure on an earlier one. Add multiple invites to
the $invites array by calling makeInvite() multiple times with different codes
so that the test properly verifies the action's behavior when handling a 429
error in a multi-invite scenario. This will ensure the test catches regressions
where the purge continues attempting to delete invites after receiving
rate-limit failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 4f933417-ffd6-443b-987c-b9f0772ff206

📥 Commits

Reviewing files that changed from the base of the PR and between f173c39 and 37914dc.

📒 Files selected for processing (2)
  • app-modules/integration-discord/src/Sync/Actions/PurgeUnusedInvitesAction.php
  • app-modules/integration-discord/tests/Unit/Sync/PurgeUnusedInvitesActionTest.php

Comment thread app-modules/integration-discord/src/Sync/Actions/PurgeUnusedInvitesAction.php Outdated
Comment thread app-modules/integration-discord/tests/Unit/Sync/PurgeUnusedInvitesActionTest.php Outdated
Fall back to X-RateLimit-Reset-After header when
the JSON body has no retry_after field.
Catch CloudflareIpBanException separately to break
the loop and count remaining invites as failed.
@gvieira18 gvieira18 merged commit 65a7e21 into 4.x Jun 19, 2026
6 checks passed
@gvieira18 gvieira18 deleted the fix/purge-invites-cloudflare-429 branch June 19, 2026 01:30
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.

3 participants