Skip to content

Fix public leaderboard network recovery - #652

Open
zacjones93 wants to merge 3 commits into
mainfrom
agent/fix-public-leaderboard-network-errors
Open

Fix public leaderboard network recovery#652
zacjones93 wants to merge 3 commits into
mainfrom
agent/fix-public-leaderboard-network-errors

Conversation

@zacjones93

@zacjones93 zacjones93 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • replace the raw public leaderboard Load failed message with a connection-focused recovery state
  • add an explicit Try again action that reruns the client fallback request without reloading the page
  • add regression coverage and architecture documentation for manual recovery

Root cause

Production telemetry showed intermittent iOS browser TypeError: Load failed failures while fetching leaderboard data through the server function. The Worker and leaderboard computation remained healthy; the failure occurs in the browser transport during client navigation or refetch.

iOS Simulator testing against production through a read-only localhost fault proxy isolated the trigger:

  • a hard page load succeeds from server-rendered loader data and does not issue a client leaderboard request
  • changing divisions reruns the route loader; each interrupted GET is attempted up to four times by the browser/transport
  • after four failures, the loader falls back to the component request, which gets another four transport attempts
  • interrupting all eight leaderboard responses reproduces the exact inline Error loading leaderboard / Load failed state
  • one to three interrupted responses recover automatically; four loader failures still recover through the component fallback
  • five seconds of latency and slow-3G-like throughput both complete successfully
  • interrupting the response mid-body reproduces the failure, confirming connection loss/partial transfer—not ordinary slowness—is the trigger

The implementation intentionally does not add another application retry loop on top of those existing attempts. That would increase one failed division change from as many as 8 reads to as many as 16. Instead, it gives the viewer a clear manual recovery action once connectivity returns.

Validation

  • reproduced production behavior in iPhone 17 Pro Simulator on iOS 26.3
  • verified reset-before-headers, reset-mid-response, 5-second latency, and slow-throughput profiles
  • 21 focused leaderboard component tests passed
  • Biome check passed
  • lat check passed
  • git diff --check passed
  • GitNexus change analysis reports low risk and no affected execution flows

The full workspace type-check remains blocked by two unrelated pre-existing untracked test files (my-schedule-event-section.test.tsx and mwfc-round-breakdown.test.ts).

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The leaderboard fallback fetch now retries transient network failures with short delays. After repeated failure, the page shows a connection error and a “Try again” button. Tests and architecture documentation cover the updated behavior.

Changes

Leaderboard retry recovery

Layer / File(s) Summary
Transient fetch retry
apps/wodsmith-start/src/components/leaderboard-page-content.tsx
The leaderboard request retries recognized transient TypeError failures after 250 ms and 750 ms delays. Cancelled requests stop retrying.
Manual retry control
apps/wodsmith-start/src/components/leaderboard-page-content.tsx
The error state uses a fixed connection message. A “Try again” button restarts the leaderboard request.
Retry validation and documentation
apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx, lat.md/architecture.md
Tests cover automatic recovery and user-triggered retry. The architecture documentation describes the fallback behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  actor Viewer
  participant LeaderboardPageContent
  participant LeaderboardAPI
  Viewer->>LeaderboardPageContent: Open leaderboard
  LeaderboardPageContent->>LeaderboardAPI: Fetch leaderboard
  LeaderboardAPI-->>LeaderboardPageContent: Transient network failure
  LeaderboardPageContent->>LeaderboardAPI: Retry after backoff
  LeaderboardAPI-->>LeaderboardPageContent: Success or repeated failure
  Viewer->>LeaderboardPageContent: Click “Try again”
  LeaderboardPageContent->>LeaderboardAPI: Fetch leaderboard again
Loading

Suggested reviewers: theianjones

Poem

A rabbit taps “Try again,”
While timers hop through rain.
The board fetches once more,
Then numbers bloom ashore.
Network thumps grow light—
Retry makes the leaderboard right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: improving public leaderboard recovery from network failures.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-public-leaderboard-network-errors

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.

@zacjones93
zacjones93 marked this pull request as ready for review August 2, 2026 00:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx`:
- Around line 803-826: Add exactly one adjacent `@lat`: comment to each relevant
recovery test in the leaderboard test suite, including the tests around
getCompetitionLeaderboardFn retry behavior. The reference should identify the
documented public leaderboard recovery behavior, and no test should receive more
than one LAT comment.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 72264ee1-0bba-49cc-90d0-3a65e26c3acf

📥 Commits

Reviewing files that changed from the base of the PR and between 245b325 and a39c13b.

📒 Files selected for processing (3)
  • apps/wodsmith-start/src/components/leaderboard-page-content.tsx
  • apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx
  • lat.md/architecture.md

Comment thread apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx">

<violation number="1" location="apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx:818">
P3: The 'retries transient network failures' test only validates the first 250ms retry followed by success. The PR's core behavior includes a second 750ms retry and, when both retries are exhausted, falling through to the 'Error loading leaderboard' recovery UI — and that exhaustion path is exactly what turns a brief outage into the manual 'Try again' flow. Suggest adding a case that rejects all three attempts (TypeError twice) and asserts the final error state, plus one that verifies the second retry fires after the cumulative backoff. This guards against regressions in the retry-count/backoff and terminal-state logic.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic


expect(getCompetitionLeaderboardFn).toHaveBeenCalledTimes(1)

await act(async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P3: The 'retries transient network failures' test only validates the first 250ms retry followed by success. The PR's core behavior includes a second 750ms retry and, when both retries are exhausted, falling through to the 'Error loading leaderboard' recovery UI — and that exhaustion path is exactly what turns a brief outage into the manual 'Try again' flow. Suggest adding a case that rejects all three attempts (TypeError twice) and asserts the final error state, plus one that verifies the second retry fires after the cumulative backoff. This guards against regressions in the retry-count/backoff and terminal-state logic.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/wodsmith-start/test/components/leaderboard-page-content.test.tsx, line 817:

<comment>The 'retries transient network failures' test only validates the first 250ms retry followed by success. The PR's core behavior includes a second 750ms retry and, when both retries are exhausted, falling through to the 'Error loading leaderboard' recovery UI — and that exhaustion path is exactly what turns a brief outage into the manual 'Try again' flow. Suggest adding a case that rejects all three attempts (TypeError twice) and asserts the final error state, plus one that verifies the second retry fires after the cumulative backoff. This guards against regressions in the retry-count/backoff and terminal-state logic.</comment>

<file context>
@@ -795,6 +800,63 @@ describe("LeaderboardPageContent", () => {
+
+			expect(getCompetitionLeaderboardFn).toHaveBeenCalledTimes(1)
+
+			await act(async () => {
+				await vi.advanceTimersByTimeAsync(250)
+			})
</file context>

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.

1 participant