Skip to content

Improve OPFS sync copy error messages#3824

Open
akirk wants to merge 1 commit into
WordPress:trunkfrom
akirk:improve-opfs-sync-error-message
Open

Improve OPFS sync copy error messages#3824
akirk wants to merge 1 commit into
WordPress:trunkfrom
akirk:improve-opfs-sync-error-message

Conversation

@akirk

@akirk akirk commented Jun 24, 2026

Copy link
Copy Markdown
Member

Motivation for the change, related issues

Persistent Playground sites can fail while copying an OPFS/local-fs mount into
MEMFS during boot. The sync loop previously waited with Promise.any(), so
when all pending copy operations rejected, Firefox surfaced the generic message:

No Promise in Promise.any was resolved

That message hides the entry that failed and the underlying read/write error,
making submitted crash reports hard to diagnose.

Implementation details

  • Wrap initial OPFS-to-MEMFS copy failures with the failed MEMFS path and root
    error message.
  • Preserve the original error via cause.
  • Use Promise.race() while waiting for pending copy operations so the first
    real rejection is surfaced instead of a generic Promise.any() aggregate.
  • Add regression coverage for a failed OPFS file read during initial sync.

Example new message:

Failed to copy OPFS entry to MEMFS path "/wordpress/database.sqlite": file could not be read

Testing Instructions

npm exec nx test php-wasm-web -- --runInBand
npm exec nx typecheck php-wasm-web
npm exec nx lint php-wasm-web

Both pass locally.

Note: the test run still prints an existing unrelated Vitest warning from
tcp-over-fetch-websocket.spec.ts about an unawaited assertion.

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Improves diagnosability of OPFS→MEMFS initial sync failures by surfacing the first real underlying copy error (with path context) instead of the generic Promise.any() message, and adds a regression test for failed OPFS reads.

Changes:

  • Wrap OPFS-to-MEMFS copy errors with the failing MEMFS path and preserve the original error via cause.
  • Switch wait behavior from Promise.any() to Promise.race() to surface the first rejection.
  • Add a Vitest regression test covering a failed OPFS file read during initial sync.

Reviewed changes

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

File Description
packages/php-wasm/web/src/lib/directory-handle-mount.ts Improves error wrapping and changes promise waiting strategy to surface real copy failures.
packages/php-wasm/web/src/lib/directory-handle-mount.spec.ts Adds an in-memory OPFS test harness and a regression test for initial sync error reporting.

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

Comment on lines 193 to 195
while (stack.length === 0 && ops.length > 0) {
await Promise.any(ops);
await Promise.race(ops);
}
Comment on lines +177 to +181
throw new Error(
`Failed to copy OPFS entry "${memfsEntryPath}" ` +
`to MEMFS: ${getErrorMessage(error)}`,
{ cause: error }
);
@akirk akirk force-pushed the improve-opfs-sync-error-message branch from 2286407 to 4d4867a Compare June 24, 2026 07:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants