From c3116bc8730a5262b49d9a8a41855523204e83b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:05:36 +0000 Subject: [PATCH 1/6] Initial plan From d683f7cecf4bb0a6f13ca0773d1c6e64c255e5fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:11:13 +0000 Subject: [PATCH 2/6] Add HTTP error handling to wp core check-update command Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/core-check-update.feature | 13 ++++++++ src/Core_Command.php | 50 +++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/features/core-check-update.feature b/features/core-check-update.feature index 32ede965..791ac9c7 100644 --- a/features/core-check-update.feature +++ b/features/core-check-update.feature @@ -70,3 +70,16 @@ Feature: Check for more recent versions """ --- """ + + Scenario: Check update shows warning when version check API fails + Given a WP install + And that HTTP requests to `api.wordpress.org` will respond with: + """ + HTTP/1.1 500 Internal Server Error + """ + + When I run `wp core check-update --force-check` + Then STDERR should contain: + """ + Warning: Failed to check for updates + """ diff --git a/src/Core_Command.php b/src/Core_Command.php index b9bbb2b4..d9fccf65 100644 --- a/src/Core_Command.php +++ b/src/Core_Command.php @@ -31,6 +31,13 @@ */ class Core_Command extends WP_CLI_Command { + /** + * Stores HTTP API errors encountered during version check. + * + * @var \WP_Error|null + */ + private $version_check_error = null; + /** * Checks for WordPress updates via Version Check API. * @@ -93,7 +100,17 @@ public function check_update( $args, $assoc_args ) { ); $formatter->display_items( $updates ); } else { - WP_CLI::success( 'WordPress is at the latest version.' ); + // If there was an HTTP error during version check, show a warning + if ( $this->version_check_error ) { + WP_CLI::warning( + sprintf( + 'Failed to check for updates: %s', + $this->version_check_error->get_error_message() + ) + ); + } else { + WP_CLI::success( 'WordPress is at the latest version.' ); + } } } @@ -1439,8 +1456,18 @@ private function get_download_url( $version, $locale = 'en_US', $file_type = 'zi */ private function get_updates( $assoc_args ) { $force_check = Utils\get_flag_value( $assoc_args, 'force-check' ); + + // Reset error tracking + $this->version_check_error = null; + + // Hook into HTTP API debug to capture errors during version check + add_action( 'http_api_debug', [ $this, 'capture_version_check_error' ], 10, 5 ); + wp_version_check( [], $force_check ); + // Remove the hook after version check + remove_action( 'http_api_debug', [ $this, 'capture_version_check_error' ], 10 ); + /** * @var object{updates: array}|false $from_api */ @@ -1496,6 +1523,27 @@ private function get_updates( $assoc_args ) { return array_values( $updates ); } + /** + * Handles the http_api_debug action to capture HTTP errors during version check. + * + * @param array|WP_Error $response HTTP response or WP_Error object. + * @param string $context Context of the HTTP request. + * @param string $class HTTP transport class name. + * @param array $args HTTP request arguments. + * @param string $url URL being requested. + */ + private function capture_version_check_error( $response, $context, $class, $args, $url ) { + // Only capture errors for the version check API + if ( false === strpos( $url, 'api.wordpress.org/core/version-check' ) ) { + return; + } + + // Store the error if the response is a WP_Error + if ( is_wp_error( $response ) ) { + $this->version_check_error = $response; + } + } + /** * Clean up extra files. * From c0445e4ffb571c758b6708f7b9489e9c34bf8fa8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:13:37 +0000 Subject: [PATCH 3/6] Add context check to capture_version_check_error method Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- composer.json | 6 ++++++ src/Core_Command.php | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/composer.json b/composer.json index 6a3fe712..a9016041 100644 --- a/composer.json +++ b/composer.json @@ -79,5 +79,11 @@ }, "support": { "issues": "https://github.com/wp-cli/core-command/issues" + }, + "repositories": { + "self": { + "type": "path", + "url": "." + } } } diff --git a/src/Core_Command.php b/src/Core_Command.php index d9fccf65..44f67ab4 100644 --- a/src/Core_Command.php +++ b/src/Core_Command.php @@ -1538,6 +1538,11 @@ private function capture_version_check_error( $response, $context, $class, $args return; } + // Only capture on response, not pre_response + if ( 'response' !== $context ) { + return; + } + // Store the error if the response is a WP_Error if ( is_wp_error( $response ) ) { $this->version_check_error = $response; From ce80b88accf700fae52c2708748806a021ac4ed4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:14:09 +0000 Subject: [PATCH 4/6] Revert accidental composer.json changes --- composer.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/composer.json b/composer.json index a9016041..6a3fe712 100644 --- a/composer.json +++ b/composer.json @@ -79,11 +79,5 @@ }, "support": { "issues": "https://github.com/wp-cli/core-command/issues" - }, - "repositories": { - "self": { - "type": "path", - "url": "." - } } } From 301cfd209d7eb52bb48506e7f068fd5aac6119cc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Dec 2025 10:17:17 +0000 Subject: [PATCH 5/6] Address code review feedback: add try-finally, use str_contains, clarify unused params Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/Core_Command.php | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Core_Command.php b/src/Core_Command.php index 44f67ab4..59af8a78 100644 --- a/src/Core_Command.php +++ b/src/Core_Command.php @@ -1463,10 +1463,12 @@ private function get_updates( $assoc_args ) { // Hook into HTTP API debug to capture errors during version check add_action( 'http_api_debug', [ $this, 'capture_version_check_error' ], 10, 5 ); - wp_version_check( [], $force_check ); - - // Remove the hook after version check - remove_action( 'http_api_debug', [ $this, 'capture_version_check_error' ], 10 ); + try { + wp_version_check( [], $force_check ); + } finally { + // Ensure the hook is always removed, even if wp_version_check() throws an exception + remove_action( 'http_api_debug', [ $this, 'capture_version_check_error' ], 10 ); + } /** * @var object{updates: array}|false $from_api @@ -1526,15 +1528,23 @@ private function get_updates( $assoc_args ) { /** * Handles the http_api_debug action to capture HTTP errors during version check. * + * This method signature matches the http_api_debug action hook signature. + * Note: $class and $args parameters are not used but are required by the hook. + * * @param array|WP_Error $response HTTP response or WP_Error object. * @param string $context Context of the HTTP request. - * @param string $class HTTP transport class name. - * @param array $args HTTP request arguments. + * @param string $_class HTTP transport class name (unused). + * @param array $_args HTTP request arguments (unused). * @param string $url URL being requested. */ - private function capture_version_check_error( $response, $context, $class, $args, $url ) { - // Only capture errors for the version check API - if ( false === strpos( $url, 'api.wordpress.org/core/version-check' ) ) { + private function capture_version_check_error( $response, $context, $_class, $_args, $url ) { + // Only capture errors for the version check API using str_contains for PHP 8.0+ + // or fallback to strpos for older versions + $is_version_check_url = function_exists( 'str_contains' ) + ? str_contains( $url, 'api.wordpress.org/core/version-check' ) + : false !== strpos( $url, 'api.wordpress.org/core/version-check' ); + + if ( ! $is_version_check_url ) { return; } From fec81ec92d83bafde23bcd85f821f23bc25a46a6 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 3 Dec 2025 11:56:05 +0100 Subject: [PATCH 6/6] Lint fix --- src/Core_Command.php | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/Core_Command.php b/src/Core_Command.php index 59af8a78..6b444c31 100644 --- a/src/Core_Command.php +++ b/src/Core_Command.php @@ -99,18 +99,16 @@ public function check_update( $args, $assoc_args ) { [ 'version', 'update_type', 'package_url' ] ); $formatter->display_items( $updates ); - } else { + } elseif ( $this->version_check_error ) { // If there was an HTTP error during version check, show a warning - if ( $this->version_check_error ) { - WP_CLI::warning( - sprintf( - 'Failed to check for updates: %s', - $this->version_check_error->get_error_message() - ) - ); - } else { - WP_CLI::success( 'WordPress is at the latest version.' ); - } + WP_CLI::warning( + sprintf( + 'Failed to check for updates: %s', + $this->version_check_error->get_error_message() + ) + ); + } else { + WP_CLI::success( 'WordPress is at the latest version.' ); } } @@ -1537,14 +1535,8 @@ private function get_updates( $assoc_args ) { * @param array $_args HTTP request arguments (unused). * @param string $url URL being requested. */ - private function capture_version_check_error( $response, $context, $_class, $_args, $url ) { - // Only capture errors for the version check API using str_contains for PHP 8.0+ - // or fallback to strpos for older versions - $is_version_check_url = function_exists( 'str_contains' ) - ? str_contains( $url, 'api.wordpress.org/core/version-check' ) - : false !== strpos( $url, 'api.wordpress.org/core/version-check' ); - - if ( ! $is_version_check_url ) { + public function capture_version_check_error( $response, $context, $_class, $_args, $url ) { + if ( false !== strpos( $url, 'api.wordpress.org/core/version-check' ) ) { return; }