Skip to content

Commit

Permalink
Merge pull request #3776 from 10up/fix/issue-3729
Browse files Browse the repository at this point in the history
Better handle failed queries on the Stats page
  • Loading branch information
felipeelia authored Dec 6, 2023
2 parents 36e6ce9 + da033e8 commit e23bec5
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 15 deletions.
49 changes: 46 additions & 3 deletions includes/classes/Stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ class Stats {
*/
protected $nodes = 0;

/**
* Failed queries and their errors.
*
* @since 5.0.1
* @var string
*/
protected $failed_queries = [];

/**
* Makes an api call to elasticsearch endpoint
*
Expand All @@ -83,13 +91,29 @@ class Stats {
protected function remote_request_helper( $path ) {
$request = Elasticsearch::factory()->remote_request( $path );

if ( is_wp_error( $request ) || empty( $request ) ) {
if ( empty( $request ) ) {
return false;
}

if ( is_wp_error( $request ) ) {
$this->failed_queries[] = [
'path' => $path,
'error' => $request->get_error_message(),
];
return false;
}

$body = wp_remote_retrieve_body( $request );
$body = wp_remote_retrieve_body( $request );
$return = json_decode( $body, true );

return json_decode( $body, true );
if ( ! empty( $return['errors'] ) ) {
$this->failed_queries[] = [
'path' => $path,
'error' => wp_json_encode( $return['errors'] ),
];
}

return $return;
}

/**
Expand Down Expand Up @@ -292,6 +316,25 @@ public function convert_to_readable_size( $size ) {
return round( pow( 1024, $base - floor( $base ) ), 1 ) . $suffix[ $f_base ];
}

/**
* Return all failed queries.
*
* @return array
* @since 5.0.1
*/
public function get_failed_queries() {
return $this->failed_queries;
}

/**
* Clear all failed queries registered.
*
* @since 5.0.1
*/
public function clear_failed_queries() {
$this->failed_queries = [];
}

/**
* Return singleton instance of class
*
Expand Down
24 changes: 21 additions & 3 deletions includes/partials/stats-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,33 @@

Stats::factory()->build_stats();

$index_health = Stats::factory()->get_health();
$totals = Stats::factory()->get_totals();
$index_health = Stats::factory()->get_health();
$totals = Stats::factory()->get_totals();
$failed_queries = Stats::factory()->get_failed_queries();
?>

<div class="error-overlay <?php if ( ! empty( $index_meta ) ) : ?>syncing<?php endif; ?>"></div>
<div class="wrap metabox-holder">
<h1><?php esc_html_e( 'Index Health', 'elasticpress' ); ?></h1>

<?php if ( ! empty( $index_health ) ) : ?>
<?php if ( ! empty( $failed_queries ) ) : ?>
<p>
<?php esc_html_e( 'It seems some requests to Elasticsearch failed and it was not possible to build your stats properly:', 'elasticpress' ); ?>
</p>
<ul>
<?php foreach ( $failed_queries as $failed_query ) : ?>
<li>
<?php
printf(
'<code>%1$s</code>: <code>%2$s</code>',
esc_html( $failed_query['path'] ),
esc_html( $failed_query['error'] )
);
?>
</li>
<?php endforeach; ?>
</ul>
<?php elseif ( ! empty( $index_health ) ) : ?>
<div class="ep-flex-container">
<div class="stats-list postbox">
<h2 class="hndle stats-list-th"><span><?php esc_html_e( 'Index list', 'elasticpress' ); ?></span><span><?php esc_html_e( 'Health', 'elasticpress' ); ?></span></h2>
Expand Down
81 changes: 72 additions & 9 deletions tests/php/TestStats.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
namespace ElasticPressTest;

use ElasticPress;
use ElasticPress\Elasticsearch;
use ElasticPress\Indexables;
use ElasticPress\Stats;

/**
* Stats test class
Expand All @@ -29,10 +32,10 @@ public function set_up() {

wp_set_current_user( $admin_id );

ElasticPress\Elasticsearch::factory()->delete_all_indices();
ElasticPress\Indexables::factory()->get( 'post' )->put_mapping();
Elasticsearch::factory()->delete_all_indices();
Indexables::factory()->get( 'post' )->put_mapping();

ElasticPress\Indexables::factory()->get( 'post' )->sync_manager->reset_sync_queue();
Indexables::factory()->get( 'post' )->sync_manager->reset_sync_queue();

$this->setup_test_post_type();

Expand All @@ -41,6 +44,8 @@ public function set_up() {
global $hook_suffix;
$hook_suffix = 'sites.php';
set_current_screen();

Stats::factory()->clear_failed_queries();
}

/**
Expand All @@ -65,15 +70,17 @@ public function tear_down() {
*/
public function testTotals() {
$this->ep_factory->post->create();
ElasticPress\Elasticsearch::factory()->refresh_indices();
Elasticsearch::factory()->refresh_indices();

ElasticPress\Stats::factory()->build_stats();
Stats::factory()->build_stats();

$totals = ElasticPress\Stats::factory()->get_totals();
$totals = Stats::factory()->get_totals();

$this->assertEquals( 1, $totals['docs'] );
$this->assertTrue( ! empty( $totals['size'] ) );
$this->assertTrue( ! empty( $totals['memory'] ) );

$this->assertEmpty( Stats::factory()->get_failed_queries() );
}

/**
Expand All @@ -84,13 +91,69 @@ public function testTotals() {
*/
public function testHealth() {
$this->ep_factory->post->create();
ElasticPress\Elasticsearch::factory()->refresh_indices();
Elasticsearch::factory()->refresh_indices();

ElasticPress\Stats::factory()->build_stats();
Stats::factory()->build_stats();

$health = ElasticPress\Stats::factory()->get_health();
$health = Stats::factory()->get_health();

$this->assertEquals( 1, count( $health ) );
$this->assertEquals( 'exampleorg-post-1', array_keys( $health )[0] );
}

/**
* Test if a failed query is registered if a request returns a WP_Error
*
* @since 5.0.1
* @group stats
*/
public function test_failed_queries_wp_error() {
add_filter( 'ep_intercept_remote_request', '__return_true' );

$return_wp_error = function () {
return new \WP_Error( 'code', 'Message' );
};
add_filter( 'ep_do_intercept_request', $return_wp_error );

Stats::factory()->build_stats( true );
$failed_queries = Stats::factory()->get_failed_queries();
$this->assertSame(
[
[
'path' => '_stats?format=json',
'error' => 'Message',
],
],
$failed_queries
);
}

/**
* Test if a failed query is registered if a request returns an Elasticsearch error
*
* @since 5.0.1
* @group stats
*/
public function test_failed_queries_es_error() {
add_filter( 'ep_intercept_remote_request', '__return_true' );

$return_es_error = function () {
return [
'body' => wp_json_encode( [ 'errors' => [ 'some error data' ] ] ),
];
};
add_filter( 'ep_do_intercept_request', $return_es_error );

Stats::factory()->build_stats( true );
$failed_queries = Stats::factory()->get_failed_queries();
$this->assertSame(
[
[
'path' => '_stats?format=json',
'error' => '["some error data"]',
],
],
$failed_queries
);
}
}

0 comments on commit e23bec5

Please sign in to comment.