From bbd4f3d99303a8f2e1daa729b42c8ad8764cc2ef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:15:57 +0000 Subject: [PATCH 1/5] Initial plan From 4fcf188e61c79e7eda24940e1bf7f22e548c66e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:19:08 +0000 Subject: [PATCH 2/5] Add exception handling to REPL to prevent session crashes Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/shell.feature | 38 ++++++++++++++++++++++++++++++++++++++ src/WP_CLI/Shell/REPL.php | 19 +++++++++++++++---- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index d5595506..4cb42887 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -77,3 +77,41 @@ Feature: WordPress REPL """ history: -1: invalid option """ + + Scenario: Exception handling preserves session state + Given a WP install + And a session file: + """ + $foo = 'test_value'; + require 'nonexistent_file.txt'; + echo $foo; + """ + + When I run `wp shell --basic < session` + Then STDOUT should contain: + """ + test_value + """ + And STDERR should contain: + """ + Error: Failed opening required 'nonexistent_file.txt' + """ + + Scenario: Exception handling for expression errors + Given a WP install + And a session file: + """ + $bar = 'preserved'; + nonexistent_function(); + $bar; + """ + + When I run `wp shell --basic < session` + Then STDOUT should contain: + """ + string(9) "preserved" + """ + And STDERR should contain: + """ + Call to undefined function nonexistent_function() + """ diff --git a/src/WP_CLI/Shell/REPL.php b/src/WP_CLI/Shell/REPL.php index 99b8f1f8..3e0604fb 100644 --- a/src/WP_CLI/Shell/REPL.php +++ b/src/WP_CLI/Shell/REPL.php @@ -29,8 +29,13 @@ public function start() { if ( self::starts_with( self::non_expressions(), $line ) ) { ob_start(); - // phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval. - eval( $line ); + try { + // phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval. + eval( $line ); + } catch ( \Throwable $e ) { + // Display the error message but continue the session + fwrite( STDERR, $e . "\n" ); + } $out = (string) ob_get_clean(); if ( 0 < strlen( $out ) ) { $out = rtrim( $out, "\n" ) . "\n"; @@ -43,8 +48,14 @@ public function start() { // Write directly to STDOUT, to sidestep any output buffers created by plugins ob_start(); - // phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval. - $evl = eval( $line ); + try { + // phpcs:ignore Squiz.PHP.Eval.Discouraged -- This is meant to be a REPL, no way to avoid eval. + $evl = eval( $line ); + } catch ( \Throwable $e ) { + // Display the error message but continue the session + fwrite( STDERR, $e . "\n" ); + $evl = null; + } $out = (string) ob_get_clean(); if ( 0 < strlen( $out ) ) { echo rtrim( $out, "\n" ) . "\n"; From a234f7c94dea80db64987fe2b4bcbf173b2948de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:20:44 +0000 Subject: [PATCH 3/5] Improve error message format for better user experience Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/Shell/REPL.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WP_CLI/Shell/REPL.php b/src/WP_CLI/Shell/REPL.php index 3e0604fb..5008adc4 100644 --- a/src/WP_CLI/Shell/REPL.php +++ b/src/WP_CLI/Shell/REPL.php @@ -34,7 +34,7 @@ public function start() { eval( $line ); } catch ( \Throwable $e ) { // Display the error message but continue the session - fwrite( STDERR, $e . "\n" ); + fwrite( STDERR, get_class( $e ) . ': ' . $e->getMessage() . "\n" ); } $out = (string) ob_get_clean(); if ( 0 < strlen( $out ) ) { @@ -53,7 +53,7 @@ public function start() { $evl = eval( $line ); } catch ( \Throwable $e ) { // Display the error message but continue the session - fwrite( STDERR, $e . "\n" ); + fwrite( STDERR, get_class( $e ) . ': ' . $e->getMessage() . "\n" ); $evl = null; } $out = (string) ob_get_clean(); From c62bc6b9541e3b0d84481798be6309131773594d Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 4 Feb 2026 14:23:56 -0500 Subject: [PATCH 4/5] Update features/shell.feature Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- features/shell.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/shell.feature b/features/shell.feature index 4cb42887..e3f103bf 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -113,5 +113,5 @@ Feature: WordPress REPL """ And STDERR should contain: """ - Call to undefined function nonexistent_function() + Error: Call to undefined function nonexistent_function() """ From 6a4f313b8a4fae31e9021c7d3d0f007960085fec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 19:27:33 +0000 Subject: [PATCH 5/5] Fix test failures: use 'try' instead of 'run' for STDERR output Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/shell.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/shell.feature b/features/shell.feature index e3f103bf..3fcf6ec8 100644 --- a/features/shell.feature +++ b/features/shell.feature @@ -87,7 +87,7 @@ Feature: WordPress REPL echo $foo; """ - When I run `wp shell --basic < session` + When I try `wp shell --basic < session` Then STDOUT should contain: """ test_value @@ -106,7 +106,7 @@ Feature: WordPress REPL $bar; """ - When I run `wp shell --basic < session` + When I try `wp shell --basic < session` Then STDOUT should contain: """ string(9) "preserved"