Skip to content

Harden pre-publish projection and client-metadata error handling#149

Draft
pfefferle wants to merge 6 commits into
trunkfrom
fix/pre-publish-error-handling
Draft

Harden pre-publish projection and client-metadata error handling#149
pfefferle wants to merge 6 commits into
trunkfrom
fix/pre-publish-error-handling

Conversation

@pfefferle

Copy link
Copy Markdown
Member

Proposed changes:

Follow-up to #148, addressing @kraftbj/@jeherve review notes that are about the pre-publish panel / client-metadata rather than the reactions block, kept out of that PR to avoid scope creep.

  • Pre-publish controller (get_preview): Post::project() runs the_content over raw, unsaved editor markup, so a malformed block or a misbehaving content/shortcode filter could throw and fatal the keystroke-driven endpoint into an opaque 500. It's now wrapped in try/catch(\Throwable)/finally — on a throw it logs the post ID via debug_log() and returns a structured WP_Error (500); the finally still removes the HTTP-blocking filter on every path.
  • Pre-publish panel (plugin.js): the fetch .catch previously collapsed every failure into one generic message and threw the error away. It now logs the error and shows a distinct message for permission failures (401/403 or rest_forbidden) vs transient ones.
  • Client-metadata controller: an invalid atmosphere_client_metadata filter return was only surfaced via _doing_it_wrong(), which is silent in production. It now also routes through debug_log(), so operators can opt into the signal via the atmosphere_debug_log filter without enabling WP_DEBUG site-wide.

Other information:

  • Have you written new tests for your changes, if applicable?

Testing instructions:

  • composer lint && npm run lint:js && npm run build
  • npm run env-test — 720 tests pass, incl. the new test_preview_returns_error_when_projection_throws (a throwing the_content filter → WP_Error 500, not a fatal).

Manual:

  1. In the editor, the Bluesky pre-publish panel still previews normally.
  2. If the projection can't be generated, the panel shows a clear message (and a distinct one for permission errors) instead of a bare "couldn't load".

Changelog entry

Entry included at .github/changelog/fix-pre-publish-error-handling (Patch / Fixed).

- Pre-publish controller: catch any Throwable from project() (it runs
  the_content over raw editor markup), log the post ID, and return a
  WP_Error 500 instead of fatalling the keystroke-driven endpoint.
- Pre-publish panel: capture and log the fetch error, and show a distinct
  message for permission failures vs transient ones rather than
  collapsing every failure into one generic line.
- Client-metadata controller: also route an invalid-filter return through
  debug_log(), so operators get a signal without WP_DEBUG (the existing
  _doing_it_wrong() is silent in production).
@pfefferle pfefferle self-assigned this Jun 19, 2026
@pfefferle pfefferle requested a review from a team June 19, 2026 07:09

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

This PR hardens error handling for the editor pre-publish preview (server projection + panel UI) and improves operational visibility when the OAuth client-metadata filter returns invalid data.

Changes:

  • Wrap pre-publish projection in try/catch(\Throwable) to return a structured WP_Error (and ensure the HTTP-blocking filter is always removed).
  • Improve the pre-publish panel’s fetch error handling by logging the underlying error and showing a distinct message for authorization failures.
  • Log invalid atmosphere_client_metadata filter results via debug_log() in addition to _doing_it_wrong(), and add a regression test for projection throws.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/phpunit/tests/rest/admin/class-test-pre-publish-controller.php Adds coverage ensuring projection exceptions return a structured REST error instead of fatalling.
src/pre-publish-panel/plugin.js Preserves the caught error, logs it, and displays more specific user-facing error messages.
includes/rest/class-client-metadata-controller.php Adds debug_log() signal when filtered client-metadata is invalid in production.
includes/rest/admin/class-pre-publish-controller.php Catches projection exceptions, logs context, returns WP_Error, and preserves finally cleanup.
build/pre-publish-panel/plugin.js Updates built panel bundle to reflect source changes.
build/pre-publish-panel/plugin.asset.php Updates build asset version hash.
.github/changelog/fix-pre-publish-error-handling Adds patch changelog entry describing improved preview error messaging.
Files not reviewed (1)
  • build/pre-publish-panel/plugin.js: Generated file

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

Comment on lines +101 to +106
const errorStatus = error?.data?.status;
const isAuth =
401 === errorStatus ||
403 === errorStatus ||
'rest_forbidden' === error?.code;

A 403 with code rest_cookie_invalid_nonce is transient, so key the auth
message off the REST error code and exclude the nonce case; it now shows
the retriable message instead of "you don't have permission".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants