Skip to content

Conversation

@fredrikekelund
Copy link
Contributor

Related issues

Proposed Changes

After the 1.7.0 launch, we've seen an increased number of Failed to start server and Failed to create server errors. We know this stems from the CLI launch, and the errors are captured in Sentry, but we don't record enough details to know exactly what's going on.

This PR fixes that by:

  1. Changing the CliCommandEventEmitter's failure event to contain a new custom error class in the payload.
  2. This custom error class (CliCommandError) captures the last error message sent over IPC (probably the most vital piece of information), stderr, stdout, the process's exit code, or the type of signal that interrupted the process.
  3. All site CLI commands now pass the output: 'capture' config to executeCliCommand. If something unexpected is printed to stderr or stdout in the child process, we will now capture it, too.

Testing Instructions

  1. Add a line somewhere in cli/commands/site/start.ts that just throws an error, like throw new Error( 'TEST ERROR' );
  2. Run npm start
  3. Start a server
  4. Ensure that you see the following in your terminal:
Sentry Logger [log]: Captured error event `[Last error message] Failed to start WordPress server: TEST ERROR

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

@fredrikekelund fredrikekelund requested review from a team and bcotrim January 27, 2026 13:42
@fredrikekelund fredrikekelund self-assigned this Jan 27, 2026
@wpmobilebot
Copy link

📊 Performance Test Results

Comparing 771f78e vs trunk

site-editor

Metric trunk 771f78e Diff Change
load 2894.00 ms 2899.00 ms +5.00 ms 🔴 0.2%

site-startup

Metric trunk 771f78e Diff Change
siteCreation 8064.00 ms 7091.00 ms -973.00 ms 🟢 -12.1%
siteStartup 3925.00 ms 3922.00 ms -3.00 ms 🟢 -0.1%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change

Comment on lines -103 to -104
child.on( 'exit', ( code ) => {
capturedExitCode = code;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed the exit event handler, because it's redundant. The close event already provides the same params as the exit event.


function appQuitHandler() {
const pid = child.pid;
child.removeAllListeners();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is unlikely to have any discernible effect, but it still makes sense in principle: this function runs before we quit the app. It kills the child process with a SIGTERM signal. If we initiated the process shutdown and the app is quitting anyway, then we don't need to listen for any more events on child

Copy link
Member

@sejas sejas left a comment

Choose a reason for hiding this comment

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

I edited stop.ts to throw an error, tested it, and confirmed that I see the error message in the Node console.

Image

I also tested importing a SQL file. And the error appeared in the console and in the dialog.

Image Image

}

async delete( deleteFiles: boolean ): Promise< void > {
async delete( trashFiles: boolean ): Promise< void > {
Copy link
Member

Choose a reason for hiding this comment

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

Renaming the trashFiles parameter seems not related to this PR but it's ok to keep it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I should've commented on that, but that was intentional on my part. Just clarifies what the param does 👍

Copy link
Contributor

@gcsecsey gcsecsey left a comment

Choose a reason for hiding this comment

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

I added the test error, and it's shown both in the alert box and in the console. 👍

Image Image

}

child.on( 'close', ( code ) => {
child.on( 'close', ( exitCode, signal ) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As a general FYI, here's from the Node.js docs:

If the process exited, code is the final exit code of the process, otherwise null. If the process terminated due to receipt of a signal, signal is the string name of the signal, otherwise null. One of the two will always be non-null.

export type CliCommandResult = {
stdout: string;
stderr: string;
exitCode: number;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The value of exitCode is now implicit based on whether we emit a success or failure event.

@fredrikekelund fredrikekelund merged commit ee9e380 into trunk Jan 27, 2026
15 checks passed
@fredrikekelund fredrikekelund deleted the stu-1260-record-error-detail-on-cli-fail branch January 27, 2026 14:39
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.

5 participants