Skip to content

[Website] Provide better UX for wasm and script download failures#3348

Open
brandonpayton wants to merge 13 commits intotrunkfrom
worktree-fix-download-error-handling
Open

[Website] Provide better UX for wasm and script download failures#3348
brandonpayton wants to merge 13 commits intotrunkfrom
worktree-fix-download-error-handling

Conversation

@brandonpayton
Copy link
Member

@brandonpayton brandonpayton commented Mar 6, 2026

Summary

  • Detect network/download failures during boot by pattern-matching the error cause chain and show a dedicated "Could not download required files" modal with actionable guidance
  • Add an inline HTML fallback ("Could not load Playground") in index.html when the main app module fails to load entirely (before React is available)
  • Add findDownloadErrorInCauseChain() utility that walks error cause chains to detect fetch failures, dynamic import errors, and WebAssembly compile/link errors (including Comlink-serialized variants)
  • Applied to both playground-website and playground-personal-wp

Download error modal

When a resource fails to download during boot (PHP WASM binary, WordPress zip, etc.), users see actionable guidance:

download-error-modal

Inline fallback (main module fails to load)

When the app module itself can't load (severe network issue, broken cache), a plain HTML fallback is shown without requiring React:

inline-fallback

Matched error patterns

Pattern Source
TypeError: Failed to fetch Standard fetch API
TypeError: Importing a module script failed Safari module imports
TypeError: error loading dynamically imported module Chrome/Firefox dynamic imports
TypeError: NetworkError when attempting to fetch Firefox fetch
TypeError: Load failed Safari fetch
WebAssembly.CompileError / LinkError WASM compile of non-WASM response (e.g. HTML error page)

Also handles Comlink-serialized errors via originalErrorClassName.

E2E test approach

The download error modal E2E test dispatches the resource-download-failed error directly through the Redux store (exposed on window.__PLAYGROUND_STORE__ in dev mode). Triggering a real download error in E2E is impractical because the PHP WASM binary and WordPress files are fetched by a Web Worker, whose network requests Playwright cannot intercept. The error detection logic is covered by 28 unit tests in error-utils.spec.ts; the E2E test verifies the modal UI renders correctly.

Test plan

  • Unit tests: 28 tests pass for findDownloadErrorInCauseChain and findFirewallErrorInCauseChain
  • E2E: inline fallback appears when main module fails to load
  • E2E: download error modal renders with correct title, body, and reload button
  • Manual: block *.wasm requests in devtools Network tab, load Playground — should show "Could not download required files" modal
  • Manual: kill dev server mid-load to verify index.html inline fallback appears

@brandonpayton brandonpayton self-assigned this Mar 6, 2026
@brandonpayton brandonpayton changed the title Catch download errors and show actionable error messages [Web] Notify user of asset download errors instead of stopping at blank screen Mar 6, 2026
@brandonpayton brandonpayton changed the title [Web] Notify user of asset download errors instead of stopping at blank screen [Web] Report asset download errors instead of stopping at blank screen Mar 6, 2026
Detect network/download failures by pattern-matching error messages in
the cause chain (TypeError "Failed to fetch", module import failures,
WebAssembly CompileError/LinkError) and show a dedicated error view with
actionable guidance instead of the generic "Playground crashed" message.

Also render an inline fallback in index.html when the initial app module
fails to load before React is available.
The download error E2E test (`?php=0.0`) was broken for two reasons:
1. Blueprint validation rejects `0.0` before reaching the PHP loader
2. Vite's import-analysis plugin catches `@php-wasm/web-0-0` at
   transform time, preventing the module from loading at all

Fix: Remove the non-existent module import approach. Instead, expose
the Redux store on `window.__PLAYGROUND_STORE__` in dev mode and have
the E2E test dispatch the error action directly. Error detection logic
is already covered by comprehensive unit tests; the E2E test now
verifies the modal UI renders correctly.

Also includes from the parent commit:
- Async/await fix for cache-busted retry in index.html fallback
- Expanded unit tests for findFirewallErrorInCauseChain
@brandonpayton brandonpayton force-pushed the worktree-fix-download-error-handling branch from 4a8aa1a to aa02b9b Compare March 13, 2026 05:26
@brandonpayton brandonpayton changed the title [Web] Report asset download errors instead of stopping at blank screen [Website] Catch download errors and show actionable error messages Mar 13, 2026
These screenshots document the two error states tested by the
error-handling E2E tests. They can be removed after PR review.
The test 'should prefer instanceof match over name match' had an unused
`wrapper` variable and didn't actually test what it claimed — the
`namedError` was disconnected from the chain. Rewire the test to build
a proper chain (outer → namedError → realFirewall) and assert that the
first match encountered while walking the chain is returned.
@brandonpayton
Copy link
Member Author

It's strange the E2E tests are failing here because they are passing on my desktop. We'll have to debug those.

I'll still mark this as ready for review.

@brandonpayton brandonpayton marked this pull request as ready for review March 14, 2026 07:21
@brandonpayton brandonpayton requested review from a team, Copilot and fellyph March 14, 2026 07:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds robust boot-time download failure detection and user-facing fallbacks so users see actionable guidance when required resources (or the app module itself) can’t be fetched.

Changes:

  • Introduce findDownloadErrorInCauseChain() and unit tests to detect fetch/import/WASM download failures via error cause chains
  • Surface a dedicated “Could not download required files” modal in both website and personal-wp boot flows
  • Add a pre-React inline HTML fallback in index.html when the main module import fails; add E2E coverage for both fallback and modal

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/playground/wordpress-builds/src/sqlite-database-integration/get-sqlite-driver-module-details.ts Removes stray whitespace in switch statement.
packages/playground/website/src/lib/state/redux/store.ts Exposes Redux store on window in dev for E2E-driven state injection.
packages/playground/website/src/lib/state/redux/slice-ui.ts Adds resource-download-failed to site error union.
packages/playground/website/src/lib/state/redux/error-utils.ts Adds download error detection via message/class-name pattern matching across cause chain.
packages/playground/website/src/lib/state/redux/error-utils.spec.ts Adds unit tests for download + firewall error detection helpers.
packages/playground/website/src/lib/state/redux/boot-site-client.ts Dispatches resource-download-failed when download-like errors occur.
packages/playground/website/src/components/site-error-modal/get-site-error-view.tsx Adds a dedicated UI view for download failures and prioritizes it over blueprint step view.
packages/playground/website/playwright/e2e/error-handling.spec.ts Adds E2E coverage for module-load inline fallback and download-error modal rendering.
packages/playground/website/index.html Adds inline HTML fallback template and renders it when ./src/main import fails (including cache-busted retry).
packages/playground/remote/remote.html Updates “report an issue” links to point to the correct repository.
packages/playground/personal-wp/src/lib/state/redux/slice-ui.ts Adds resource-download-failed to site error union.
packages/playground/personal-wp/src/lib/state/redux/error-utils.ts Adds download error detection helper mirroring website implementation.
packages/playground/personal-wp/src/lib/state/redux/boot-site-client.ts Dispatches resource-download-failed when download-like errors occur.
packages/playground/personal-wp/src/components/site-error-modal/get-site-error-view.tsx Adds a dedicated UI view for download failures and prioritizes it over blueprint step view.
packages/playground/personal-wp/index.html Adds inline HTML fallback template and renders it when ./src/main import fails (including cache-busted retry).

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

brandonpayton and others added 2 commits March 14, 2026 03:26
@brandonpayton brandonpayton changed the title [Website] Catch download errors and show actionable error messages [Website] Provide better UX for wasm and script download failures Mar 14, 2026
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