Skip to content

fix: fall back to fetch when prerender returns 4xx - #276

Merged
Kikobeats merged 1 commit into
masterfrom
fix/prerender-4xx-fallback
Aug 17, 2026
Merged

fix: fall back to fetch when prerender returns 4xx#276
Kikobeats merged 1 commit into
masterfrom
fix/prerender-4xx-fallback

Conversation

@Kikobeats

@Kikobeats Kikobeats commented Aug 17, 2026

Copy link
Copy Markdown
Member

Bug and impact

prerender() starts got and Chrome in parallel, then treats any page.content() as success and cancels fetch. A CloudFront/WAF 403 document is still a successful page.content(), so a parallel 200 fetch is dropped. That is how https://www.un.org/en/about-us kept the challenge page while prerender=false returned the real HTML.

Root cause

Chrome success is defined as “got a document”, not “got a usable status”. Fetch is only used when Chrome throws.

Fix

If prerender statusCode >= 400, wait for fetch. Use fetch when it is a 2xx/3xx. Otherwise keep the prerender document (both blocked, or fetch rejected).

Validation

  • prerender 4xx falls back to a successful fetch — mocked Chrome 403 + local 200 → mode: fetch, statusCode: 200
  • prerender 4xx is kept when fetch is also unsuccessful — mocked Chrome 403 + local 403 → keep prerender 403
  • pnpm exec ava test/mode.js passed

Made with Cursor

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of prerendered pages returning client or server error statuses.
    • When available, the app now displays successfully fetched content instead of the prerendered error response.
    • Preserved prerendered error pages when the fallback fetch is unsuccessful.
  • Tests

    • Added coverage for successful and unsuccessful fallback behavior, including response status, rendering mode, and displayed content.

page.content() treats WAF/challenge HTML as success and cancelled
a parallel 2xx fetch.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 502498fd-fe4a-4fe3-9391-05bf96c4f128

📥 Commits

Reviewing files that changed from the base of the PR and between 0063335 and b189095.

📒 Files selected for processing (2)
  • src/index.js
  • test/mode.js

Included review availability: Your plan includes up to 2 reviews per rolling hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The prerender flow now checks error responses before canceling the fetch request. It returns a successful fetch response when available and preserves the prerender response when the fetch also fails. Tests cover both outcomes.

Changes

Prerender fallback handling

Layer / File(s) Summary
Error response fallback logic
src/index.js
For prerendered 4xx or 5xx responses, the flow returns a non-error fetch response when available. Otherwise, it continues with the prerender response.
Fallback mode validation
test/mode.js
Tests verify that a successful fallback returns fetched content in fetch mode and that a failed fallback preserves prerender mode, status, and error HTML.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to b1890

This localized change makes prerendered 4xx responses fall back to a successful fetch while preserving the prerender result when both responses fail; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: using fetch as a fallback when prerender returns a 4xx response.
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.
✨ 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 fix/prerender-4xx-fallback

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.

@Kikobeats
Kikobeats merged commit c4b1ab4 into master Aug 17, 2026
4 checks passed
@Kikobeats
Kikobeats deleted the fix/prerender-4xx-fallback branch August 17, 2026 12:41
Kikobeats added a commit that referenced this pull request Aug 18, 2026
* fix: keep fetch when shadow-DOM prerender retry is 4xx

#276 only cancelled a parallel fetch when prerender itself was
usable. The auto-mode shadow-DOM upgrade still treated WAF/challenge
HTML from page.content() as success and replaced a working 2xx fetch.

Co-authored-by: kikohumanbeatbox <kikohumanbeatbox@gmail.com>

* test: share shadow-DOM HTML fixture

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: kikohumanbeatbox <kikohumanbeatbox@gmail.com>
Co-authored-by: Kiko Beats <josefrancisco.verdu@gmail.com>
Kikobeats pushed a commit that referenced this pull request Aug 20, 2026
#276 returns the parallel fetch (mode: fetch, 2xx) when page.content()
is a 4xx challenge. The #277 upgrade guard only checked status, so that
later fetch replaced the already-good first snapshot — including a 200
soft-block or interstitial body.

Only accept a successful prerender result for the auto-mode upgrade.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
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