Skip to content

test: add production coverage for global-error compat#556

Merged
james-elicx merged 3 commits intocloudflare:mainfrom
NathanDrake2406:fix/app-router-error-boundary-200
Mar 16, 2026
Merged

test: add production coverage for global-error compat#556
james-elicx merged 3 commits intocloudflare:mainfrom
NathanDrake2406:fix/app-router-error-boundary-200

Conversation

@NathanDrake2406
Copy link
Copy Markdown
Contributor

Summary

This updates the App Router global-error compat coverage to reflect current vinext behavior and adds production-preview assertions for the HTTP-level cases that were previously tracked as skipped.

What Changed

  • added production-preview coverage in tests/nextjs-compat/global-error.test.ts for:
    • local error.tsx on server component errors
    • nearest nested error.tsx
    • local error.tsx for generateMetadata() errors
    • global-error.tsx fallback when metadata has no local boundary
  • updated tests/nextjs-compat/TRACKING.md to mark those cases as passing instead of skipped
  • left runtime code unchanged because the bug no longer reproduces on current upstream/main

Why It Matters

The tracker was claiming a meaningful Next.js compatibility bug around handled errors returning 500 instead of 200. The current implementation already matches Next.js for the server-side HTTP semantics here, so the right fix is to lock that behavior in with direct coverage and stop advertising a stale regression.

Risks Or Limits

  • this does not add the browser-only global-error interactions from the upstream Next.js suite
  • the production-preview block adds build time to this one compat file, but it directly covers the disputed behavior that was missing from the compat suite

Verification

  • vp test tests/nextjs-compat/global-error.test.ts

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 16, 2026

Open in StackBlitz

npm i https://pkg.pr.new/vinext@556

commit: a49bd19

@NathanDrake2406 NathanDrake2406 changed the title Add production coverage for global-error compat test: add production coverage for global-error compat Mar 16, 2026
@james-elicx
Copy link
Copy Markdown
Collaborator

/bigbonk review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

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

Good direction — locking in passing behavior with production preview coverage is worthwhile. Two issues to address before merging.

Summary tables not updated

The Chunk 3 detailed table (lines 78-92) now correctly shows 6/6 pass, 0 skip. But there are two other summary tables in the same file that still say 3 pass, 3 skip for chunk 3:

  1. "Early snapshot" summary (line 67): | 3. global-error | 11 | 3 | 3 | 5 | 0 | Done |
  2. "Overall Summary" table (line 358): | 3. global-error | 11 | 3 | 3 | 5 | 0 | Done |
  3. Overall total (line 374): shows 6 skip total — should now be 3 since 3 global-error skips are resolved

These need to be updated to match the detailed table.

Missing production preview tests for routes #3 and #4

The tracker now says tests #3 (global-error-rsc) and #4 (global-error-ssr) are "Verified in dev" and marked PASS, but the production preview block only covers 4 of the 6 routes. The two global-error.tsx fallback routes (/nextjs-compat/global-error-rsc and /nextjs-compat/global-error-ssr) are absent from the production preview describe. Either add them there too for consistency, or change the tracker notes for #3 and #4 to say "Verified in dev only" to be precise about coverage scope.

Otherwise the test code itself looks correct and follows the existing createBuilder + preview pattern from app-router.test.ts.

| --- | --------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 1 | error-server-test: server component throw caught by error.tsx | PASS | Verified in dev + production preview: vinext renders the local `error.tsx` boundary with HTTP 200. |
| 2 | error-nested-test: nested error caught by inner error.tsx | PASS | Verified in dev + production preview: vinext resolves to the nearest matching `error.tsx`, not the parent boundary. |
| 3 | Server component throw without local error.tsx returns a response | PASS | Verified in dev: vinext renders `global-error.tsx` with HTTP 200 when no local boundary exists. |
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.

Tests #3 and #4 say "Verified in dev" but neither /nextjs-compat/global-error-rsc nor /nextjs-compat/global-error-ssr appears in the new production preview describe block. The production tests only cover the 4 local-boundary routes (/error-server-test, /error-nested-test/child, /nextjs-compat/metadata-error-with-boundary, /nextjs-compat/metadata-error-without-boundary).

Consider either:

  1. Adding production preview assertions for these two routes as well (for parity with the claim), or
  2. Updating the notes here to say "Verified in dev only" so the tracker accurately reflects what's tested.

| 10 | Client-side notFound() trigger from button (root) | N/A | Requires Playwright |
| 11 | Client-side notFound() trigger from button (nested) | N/A | Requires Playwright |

**Result: 6/6 pass (HTTP-level), 0 skip, 5 N/A (browser-only, dev overlay)**
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.

This line correctly shows 6/6 pass, 0 skip. But the two summary tables elsewhere in this file were not updated:

  • Line 67 ("early snapshot" summary): still says 3 pass, 3 skip
  • Line 358 ("Overall Summary"): still says 3 pass, 3 skip
  • Line 374 (total row): still says 6 skip — should be 3

Please update all three for consistency.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 16, 2026

Review submitted successfully. Here's a summary of the feedback:

Requested changes on PR #556:

  1. Summary tables not updated — The detailed Chunk 3 table correctly shows 6/6 pass, 0 skip, but the two summary tables (lines 67 and 358) and the total row (line 374) still reflect the old 3 pass, 3 skip numbers. All three need updating for consistency.

  2. Missing production preview tests for routes fix: exclude vinext from optimizeDeps to prevent virtual module resolution errors #3 and ci: Bonk should fail faster #4 — The tracker claims tests fix: exclude vinext from optimizeDeps to prevent virtual module resolution errors #3 (global-error-rsc) and ci: Bonk should fail faster #4 (global-error-ssr) are "Verified in dev" and marked PASS, but neither route appears in the new production preview describe block. The production tests only cover the 4 local-boundary routes. Either add the two missing routes to the production preview block, or update the tracker notes to say "Verified in dev only."

The test code itself is well-structured and follows the existing createBuilder + preview pattern from app-router.test.ts.

github run

@NathanDrake2406
Copy link
Copy Markdown
Contributor Author

NathanDrake2406 commented Mar 16, 2026

Addressed the requested changes in efefba9.

  • updated the stale Chunk 3 summary rows and overall totals in tests/nextjs-compat/TRACKING.md
  • added the missing production preview coverage for /nextjs-compat/global-error-rsc and /nextjs-compat/global-error-ssr
  • asserted the production contract that actually applies there: global-error.tsx renders with HTTP 200 and the error message is sanitized in production builds

Verification:

  • vp test tests/nextjs-compat/global-error.test.ts

@james-elicx
Copy link
Copy Markdown
Collaborator

/bigbonk re-review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

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

Good PR — the production preview coverage is well-structured and the tracker updates are mostly correct. One minor inconsistency remains from the previous review round.

The test code itself is solid: assertions are grounded in real implementation strings (the sanitized error message from app-rsc-entry.ts:527), negative assertions prevent false positives (e.g., not.toContain("server page error") to verify message sanitization in prod), and the createBuilder + preview pattern matches the existing convention in app-router.test.ts.

| --- | --------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 1 | error-server-test: server component throw caught by error.tsx | PASS | Verified in dev + production preview: vinext renders the local `error.tsx` boundary with HTTP 200. |
| 2 | error-nested-test: nested error caught by inner error.tsx | PASS | Verified in dev + production preview: vinext resolves to the nearest matching `error.tsx`, not the parent boundary. |
| 3 | Server component throw without local error.tsx returns a response | PASS | Verified in dev: vinext renders `global-error.tsx` with HTTP 200 when no local boundary exists. |
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.

The tracker notes for #3 and #4 still say "Verified in dev" but the test file now includes production preview assertions for both /nextjs-compat/global-error-rsc (line 212) and /nextjs-compat/global-error-ssr (line 220). These should say "Verified in dev + production preview" to match rows #1, #2, #5, and #6.

Suggested change
| 3 | Server component throw without local error.tsx returns a response | PASS | Verified in dev: vinext renders `global-error.tsx` with HTTP 200 when no local boundary exists. |
| 3 | Server component throw without local error.tsx returns a response | PASS | Verified in dev + production preview: vinext renders `global-error.tsx` with HTTP 200 when no local boundary exists. |

| 1 | error-server-test: server component throw caught by error.tsx | PASS | Verified in dev + production preview: vinext renders the local `error.tsx` boundary with HTTP 200. |
| 2 | error-nested-test: nested error caught by inner error.tsx | PASS | Verified in dev + production preview: vinext resolves to the nearest matching `error.tsx`, not the parent boundary. |
| 3 | Server component throw without local error.tsx returns a response | PASS | Verified in dev: vinext renders `global-error.tsx` with HTTP 200 when no local boundary exists. |
| 4 | Client component SSR throw without local error.tsx returns a response | PASS | Verified in dev: vinext renders `global-error.tsx` with HTTP 200 for SSR-time client component throws. |
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.

Same as above — production preview coverage exists in the test file but the note doesn't reflect it.

Suggested change
| 4 | Client component SSR throw without local error.tsx returns a response | PASS | Verified in dev: vinext renders `global-error.tsx` with HTTP 200 for SSR-time client component throws. |
| 4 | Client component SSR throw without local error.tsx returns a response | PASS | Verified in dev + production preview: vinext renders `global-error.tsx` with HTTP 200 for SSR-time client component throws. |

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 16, 2026

Review submitted. Here's a summary:

Overall: The PR is in good shape. The production preview tests are well-written — assertions use real implementation strings from app-rsc-entry.ts:527, negative assertions guard against false positives, and the createBuilder + preview pattern is consistent with app-router.test.ts. The tracker math is correct (362 -> 365 pass, 6 -> 3 skip).

One minor issue: The tracker notes for tests #3 and #4 (global-error-rsc and global-error-ssr) still say "Verified in dev" even though the author added production preview assertions for both routes in the second commit. These should say "Verified in dev + production preview" to match the other 4 rows in the chunk table.

github run

@NathanDrake2406
Copy link
Copy Markdown
Contributor Author

Updated tracker notes for tests #3 and #4 to say "Verified in dev + production preview" — matching the other 4 rows now that production preview assertions exist for both routes.

@james-elicx
Copy link
Copy Markdown
Collaborator

/bigbonk re-review

Copy link
Copy Markdown
Contributor

@ask-bonk ask-bonk bot left a comment

Choose a reason for hiding this comment

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

Looks good. The production preview tests are well-written and follow the established createBuilder + preview pattern from app-router.test.ts. Assertions are grounded in real implementation behavior — the sanitized error message from app-rsc-entry.ts:527, negative assertions against raw error messages leaking in prod, and correct boundary resolution. Tracker math is correct (362 → 365 pass, 6 → 3 skip). All CI checks pass.

One minor nit (not blocking): The "Combined Key Metrics" section at TRACKING.md:396-397 still says "400 tests passing (362 Vitest + 38 Playwright)" and "11 tests skipped (6 Vitest + 5 Playwright)". With the changes in this PR, these should be "403 tests passing (365 Vitest + 38 Playwright)" and "8 tests skipped (3 Vitest + 5 Playwright)". The actual summary tables are correct — this is just the prose section further down that's out of sync.

@ask-bonk
Copy link
Copy Markdown
Contributor

ask-bonk bot commented Mar 16, 2026

Review submitted. Here's a summary of my review:

Approved the PR. The changes are solid:

  • Production preview tests follow the established createBuilder + preview pattern from app-router.test.ts
  • Assertions are well-grounded: checks for the real sanitized error message from app-rsc-entry.ts:527, negative assertions verify error messages don't leak in prod, and boundary resolution is validated at the HTTP level
  • Tracker updates are internally consistent — the summary tables and detailed chunk table all agree on 6/6 pass, 0 skip for chunk 3, and totals (365 pass, 3 skip) are correct
  • All CI checks pass (Vitest, Playwright E2E across all projects, format, lint, typecheck)

One minor nit: The "Combined Key Metrics" prose section at TRACKING.md:396-397 still references the old totals ("400 tests passing", "11 tests skipped") instead of the updated numbers (403 passing, 8 skipped). The actual summary tables are correct — this is just a stale prose section further down.

github run

@james-elicx james-elicx merged commit f3c02b8 into cloudflare:main Mar 16, 2026
18 checks passed
@NathanDrake2406 NathanDrake2406 deleted the fix/app-router-error-boundary-200 branch March 18, 2026 09:50
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