Skip to content

fix: Handle HTML error responses in API and improve Leaderboard error UI#1

Merged
magi-9 merged 5 commits into
mainfrom
fix-leaderboard-html-error-5766281264053604882
Jan 28, 2026
Merged

fix: Handle HTML error responses in API and improve Leaderboard error UI#1
magi-9 merged 5 commits into
mainfrom
fix-leaderboard-html-error-5766281264053604882

Conversation

@google-labs-jules

Copy link
Copy Markdown
Contributor

This PR fixes an issue where the mobile app (PWA) would display raw HTML error pages (e.g. Cloudflare challenge) in a toast notification when the leaderboard API failed.

Changes:

  1. API Interceptor (frontend/src/utils/api.js): Added a check to detect if an error response contains HTML. If so, it replaces the error message with a user-friendly "Connection error" message.
  2. Leaderboard Page (frontend/src/pages/LeaderboardPage.jsx): Implemented proper error handling using React Query's isError state. The page now displays a clear error message and a "Retry" button when the leaderboard fails to load, instead of showing an empty list or "No players yet".

This improves the UX significantly when network issues or Cloudflare challenges occur.


PR created automatically by Jules for task 5766281264053604882 started by @magi-9

- Update `frontend/src/utils/api.js` to detect HTML responses (e.g. Cloudflare) and show a generic error message instead of raw HTML.
- Update `frontend/src/pages/LeaderboardPage.jsx` to handle `isError` state and provide a "Retry" button.
@google-labs-jules

Copy link
Copy Markdown
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

…PI caching

- Update `frontend/src/utils/api.js`:
    - Detect HTML responses (Cloudflare challenges) and show a generic error toast.
    - Clear `auth-storage` from localStorage on refresh failure to prevent reload loops.
- Update `frontend/src/pages/LeaderboardPage.jsx`:
    - Handle `isError` state with a user-friendly UI and "Retry" button.
- Update `frontend/vite.config.js`:
    - Configure PWA Service Worker to use `NetworkOnly` strategy for `/api/` requests, preventing caching of Cloudflare HTML challenges.
@magi-9 magi-9 assigned Copilot and unassigned Copilot Jan 26, 2026
- Backend: Fix `GameEngine.process_new_tag` validation logic (tagger must be holder).
- Frontend: Restore `package-lock.json` for CI.
- Frontend: Update `vite.config.js` to use `NetworkOnly` for API requests.
- Frontend: Update `api.js` to handle HTML errors and prevent reload loops.
- Frontend: Improve `LeaderboardPage` error UI.
@magi-9 magi-9 requested a review from Copilot January 28, 2026 12:00
@magi-9 magi-9 marked this pull request as ready for review January 28, 2026 12:01

Copilot AI 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.

Pull request overview

This PR fixes HTML error response handling in the mobile PWA and improves the leaderboard error UI. It also corrects a bug in the game engine's tag validation logic.

Changes:

  • API interceptor now detects and replaces HTML error responses with user-friendly messages
  • Leaderboard page displays proper error UI with retry functionality
  • Service worker cache strategy changed from NetworkFirst to NetworkOnly for API requests

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/src/utils/api.js Added HTML error detection, improved error messages, and auth-storage cleanup
frontend/src/pages/LeaderboardPage.jsx Added error state handling with retry button
frontend/vite.config.js Changed API cache strategy to NetworkOnly and updated URL pattern
backend/game/game_engine.py Fixed bug where tagger validation was checking the wrong user
frontend/package-lock.json Added lockfile for dependency versioning

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/src/utils/api.js
if (typeof error.response.data === 'string') {
errorMessage = error.response.data;
// Check if response is HTML (likely Cloudflare or server error page)
if (error.response.data.trim().startsWith('<')) {

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The HTML detection is too simplistic and could produce false positives. A string response that legitimately starts with '<' (e.g., a comparison message like "< 5 items found") would be incorrectly treated as HTML. Consider using a more robust check such as verifying the response content-type header or checking for HTML doctype/tags patterns.

Suggested change
if (error.response.data.trim().startsWith('<')) {
const contentType = error.response.headers?.['content-type'] || '';
const isHtmlContentType = contentType.toLowerCase().includes('text/html');
const trimmedData = error.response.data.trim();
const looksLikeHtml =
/^<!doctype html/i.test(trimmedData) ||
/^<html[\s>]/i.test(trimmedData) ||
/<body[\s>]/i.test(trimmedData);
if (isHtmlContentType || looksLikeHtml) {

Copilot uses AI. Check for mistakes.
Comment thread frontend/vite.config.js
Comment on lines +42 to +44
// Match /api/ requests (both relative and absolute if on same domain)
urlPattern: /\/api\//,
handler: 'NetworkOnly',

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The change from 'NetworkFirst' to 'NetworkOnly' strategy means API responses will never be cached. While this ensures data freshness, consider if this is the intended behavior for all API endpoints. For some endpoints (like static data or slowly-changing resources), NetworkFirst with proper cache expiration might provide better offline experience and performance.

Copilot uses AI. Check for mistakes.
Comment thread frontend/vite.config.js
Comment on lines +42 to +43
// Match /api/ requests (both relative and absolute if on same domain)
urlPattern: /\/api\//,

Copilot AI Jan 28, 2026

Copy link

Choose a reason for hiding this comment

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

The URL pattern change from /^https:\/\/api\./i to /\/api\// significantly changes matching behavior. The old pattern matched absolute URLs starting with 'https://api.' (e.g., 'https://api.example.com'), while the new pattern matches any path containing '/api/' (relative or absolute). Verify this aligns with your API routing architecture and that all API endpoints contain '/api/' in their path.

Suggested change
// Match /api/ requests (both relative and absolute if on same domain)
urlPattern: /\/api\//,
// Match absolute HTTPS requests to the api.* subdomain
urlPattern: /^https:\/\/api\./i,

Copilot uses AI. Check for mistakes.
google-labs-jules Bot and others added 2 commits January 28, 2026 12:06
- Backend: Add `pytest.ini` to configure Django settings for tests.
- Backend: Fix logic in `GameEngine.process_new_tag` (tagger must be holder).
- Frontend: Add `.eslintrc.cjs` to fix linting errors.
- Frontend: Restore `package-lock.json`.
- Frontend: Update `vite.config.js` to use `NetworkOnly` for API requests.
- Frontend: Improve error handling for HTML responses and reload loops.

Co-authored-by: magi-9 <156084637+magi-9@users.noreply.github.com>
- Backend: Fix `GameEngine` tag validation (allow holder to tag).
- Backend: Add `pytest.ini` for test configuration.
- Frontend: Add `.eslintrc.cjs` and fix all linting errors.
- Frontend: Configure PWA to use `NetworkOnly` for API (fixes Cloudflare issue).
- Frontend: Improve error handling and prevent reload loops.

Co-authored-by: magi-9 <156084637+magi-9@users.noreply.github.com>
@magi-9 magi-9 merged commit 0f68068 into main Jan 28, 2026
12 checks passed
@magi-9 magi-9 deleted the fix-leaderboard-html-error-5766281264053604882 branch January 28, 2026 12: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.

3 participants