Skip to content

Catch exceptions in REPL to preserve session state on errors#83

Draft
Copilot wants to merge 5 commits intomainfrom
copilot/catch-exceptions-restart-session
Draft

Catch exceptions in REPL to preserve session state on errors#83
Copilot wants to merge 5 commits intomainfrom
copilot/catch-exceptions-restart-session

Conversation

Copy link
Contributor

Copilot AI commented Feb 4, 2026

Plan: Add Exception Handling to Prevent Session Crashes ✅

  • Understand the current REPL implementation in src/WP_CLI/Shell/REPL.php
  • Wrap eval() calls with try-catch blocks to catch Throwable (includes both exceptions and errors)
  • Display caught errors/exceptions to the user but continue the session
  • Improve error format to show class and message (cleaner than full stack trace)
  • Add Behat test to verify exception handling works correctly
  • Fix test failures by using When I try instead of When I run for tests that expect STDERR
  • Test the implementation manually
  • Run code review and address feedback
  • Run security checks
  • All tests passing ✅

Summary

Successfully implemented exception handling in the WP-CLI shell REPL to prevent session crashes on errors. All tests now pass.

Changes Made:

  • Modified src/WP_CLI/Shell/REPL.php to wrap both eval() calls with try-catch blocks
  • Errors are caught and displayed to STDERR without crashing the session
  • Clean error format: ErrorClass: error message
  • Added 2 comprehensive Behat test scenarios to verify the fix
  • Fixed tests to use When I try for scenarios that write to STDERR

Test Results:

  • All 7 scenarios passing (35 steps)
  • Linting, code style, and static analysis checks passing
  • Security scan passing
Original prompt

This section details on the original issue you should resolve

<issue_title>Catch exceptions to avoid restarting session</issue_title>
<issue_description>## Feature Request

Describe your use case and the problem you are facing

Making typos/etc often results in a fatal error, and the session crashes and has to be restarted. After restarting, I have to recreate any variables, includes, etc from scratch, without making any fatal errors. That often makes it just too frustrating to use.

> wp shell
wp> require 'foo.txt';
Warning: require(foo.txt): Failed to open stream: No such file or directory in phar:///usr/local/bin/wp/vendor/wp-cli/shell-command/src/WP_CLI/Shell/REPL.php(32) : eval()'d code on line 1
Fatal error: Uncaught Error: Failed opening required 'foo.txt' (include_path='.:/usr/local/Cellar/php/8.0.0_1/share/php/pear') in phar:///usr/local/bin/wp/vendor/wp-cli/shell-command/src/WP_CLI/Shell/REPL.php(32) : eval()'d code:1
Stack trace:
wp-cli/shell-command#0 phar:///usr/local/bin/wp/vendor/wp-cli/shell-command/src/WP_CLI/Shell/REPL.php(32): eval()
wp-cli/shell-command#1 phar:///usr/local/bin/wp/vendor/wp-cli/shell-command/src/Shell_Command.php(51): WP_CLI\Shell\REPL->start()
wp-cli/shell-command#2 [internal function]: Shell_Command->__invoke(Array, Array)
wp-cli/shell-command#3 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(98): call_user_func(Array, Array, Array)
wp-cli/shell-command#4 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}(Array, Array)
wp-cli/shell-command#5 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(451): call_user_func(Object(Closure), Array, Array)
wp-cli/shell-command#6 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(371): WP_CLI\Dispatcher\Subcommand->invoke(Array, Array, Array)
wp-cli/shell-command#7 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(394): WP_CLI\Runner->run_command(Array, Array)
wp-cli/shell-command#8 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1160): WP_CLI\Runner->run_command_and_exit()
wp-cli/shell-command#9 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(23): WP_CLI\Runner->start()
wp-cli/shell-command#10 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/bootstrap.php(74): WP_CLI\Bootstrap\LaunchRunner->process(Object(WP_CLI\Bootstrap\BootstrapState))
wp-cli/shell-command#11 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php(27): WP_CLI\bootstrap()
wp-cli/shell-command#12 phar:///usr/local/bin/wp/php/boot-phar.php(11): include('phar:///usr/loc...')
wp-cli/shell-command#13 /usr/local/bin/wp(4): include('phar:///usr/loc...')
wp-cli/shell-command#14 {main}
  thrown in phar:///usr/local/bin/wp/vendor/wp-cli/shell-command/src/WP_CLI/Shell/REPL.php(32) : eval()'d code on line 1
Error: There has been a critical error on this website.Learn more about debugging in WordPress. There has been a critical error on this website.

Describe the solution you'd like

PHP's REPL is able to catch fatals and continue running:

php > $foo = 'stuff';
php > echo $foo;
stuff
php > require 'foo.txt';

Warning: require(foo.txt): Failed to open stream: No such file or directory in php shell code on line 1

Warning: Uncaught Error: Failed opening required 'foo.txt' (include_path='.:/usr/local/Cellar/php/8.0.0_1/share/php/pear') in php shell code:1
Stack trace:
wp-cli/shell-command#0 {main}
  thrown in php shell code on line 1
php > echo $foo;
stuff

Is that possible for wp shell ?</issue_description>

Comments on the Issue (you are @copilot in this section)

@schlessera Yes, this is something that annoys me as well. I guess it shouldn't;t be too hard to add an exception handler clause to the internal loop...?

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 4, 2026 16:19
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Catch exceptions to avoid restarting session Catch exceptions in REPL to preserve session state on errors Feb 4, 2026
Copilot AI requested a review from swissspidy February 4, 2026 16:22
@swissspidy swissspidy requested a review from Copilot February 4, 2026 19:06

This comment was marked as resolved.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@swissspidy

This comment was marked as resolved.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

Catch exceptions to avoid restarting session

2 participants