[Blueprints] Surface more activation errors from activatePlugin - #3549
Merged
Conversation
When a plugin failed to activate because activate_plugin() returned a WP_Error (unmet PHP requirement, missing plugin file, plugin already active and printing output, etc.), the thrown JS error said only "WordPress exited with exit code 0" — useless. The actual WP_Error message was sitting in the activation script's stdout, only logged as a warning, and any error_log() output during activation went to debug.log where the caller had to know to look. Route this request's PHP errors to a scratch log file owned by the step (ini_set per-request, no impact on the user's debug.log), then on failure include both the WordPress die() text and any logged PHP errors in the rejected promise. Adds a regression test for the WP_Error path, which had no coverage.
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Improves the activatePlugin blueprint step by surfacing meaningful activation failure details (WP_Error output + PHP error logs) instead of a misleading generic exit-code error, and adds a regression test for this failure mode.
Changes:
- Capture PHP
error_log()output during activation into a per-request scratch log and include it in the thrown JS error on failure. - Improve the thrown error message to include the WordPress
die()text (typically WP_Error message) and any PHP log output. - Add a regression test covering activation rejection due to unmet PHP requirements.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| packages/playground/blueprints/src/lib/steps/activate-plugin.ts | Adds scratch logging for activation and surfaces WP output + PHP logs in the thrown error message. |
| packages/playground/blueprints/src/lib/steps/activate-plugin.spec.ts | Adds a test ensuring WP_Error activation messages are surfaced to the caller. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Drain the scratch log immediately after activation so it's cleaned up on success too, not only on the failure path. - Loosen the WP_Error test regex to assert "WordPress said:" plus any non-empty content, instead of depending on the literal "PHP" appearing in WP's localized error string.
… coverage
Restored the "Response headers: {...}" trailer the previous error message had — it's the only signal when activation fails via a redirect with no body — and added a one-liner pointing readers at the Playground console (browser DevTools) or the CLI output for additional logs, so the message is useful in both environments.
Expanded the spec with assertions on specific failure messages: the WP_Error path keeps its check that the WordPress text mentions PHP, plus three new cases — missing plugin file, response-headers + console-pointer in the message, and PHP error_log() output captured into the scratch log via a plugin that prints unexpected output during sandbox scrape.
The missing-plugin test asserted the snippet's "wasn't able to find" string, but WordPress's validate_plugin returns a WP_Error("Plugin file does not exist.") before the snippet's false-fallback can trigger — assert that message instead. The error_log capture test fixture printed at file scope, which still ends up activating the plugin (per the existing comment in activate-plugin.ts), so the rejection never happened — switched to a register_activation_hook that error_logs then wp_die()s, which fires before active_plugins is written and exercises the real failure-with-log-capture path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a plugin failed to activate because
activate_plugin()returned aWP_Error(unmet PHP requirement, missing plugin file, plugin printing output during validation, etc.), the thrown JS error read "WordPress exited with exit code 0" — useless. The actual WP_Error message was sitting in the activation script's stdout, only emitted as alogger.warn, and anyerror_log()output during activation went todebug.logwhere the caller had to know to look.Route this request's PHP errors to a scratch log file owned by the step (
ini_setper-request, no impact on the user'sdebug.log), then on the failure path include both the WordPressdie()text and any logged PHP errors in the rejected promise. Drops the misleading exit-code wording, since by the time we reach that branchphp.run()has already returned with exit code 0 — non-zero exits throw upstream with stdout+stderr already.Adds a regression test for the WP_Error branch, which previously had no coverage.
Test plan
playground-blueprintstest suite, including the new "unmet PHP requirement" case