Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions projects/packages/stats/changelog/update-blog_stats_debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Improve Post Stats cache handling for invalid or error data
24 changes: 21 additions & 3 deletions projects/packages/stats/src/class-wpcom-stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -508,15 +508,15 @@ protected function fetch_post_stats( $args, $post_id ) {
|| empty( $data )
|| is_wp_error( $data )
) {
return $data;
return $this->refresh_post_stats_cache( $endpoint, $args, $post_id, $meta_name );
}

$time = key( $data );
$views = $data[ $time ] ?? null;

// Bail if data is malformed.
if ( ! is_numeric( $time ) || ! is_array( $views ) ) {
return $data;
return $this->refresh_post_stats_cache( $endpoint, $args, $post_id, $meta_name );
}

/** This filter is already documented in projects/packages/stats/src/class-wpcom-stats.php */
Expand All @@ -530,8 +530,26 @@ protected function fetch_post_stats( $args, $post_id ) {
}
}

return $this->refresh_post_stats_cache( $endpoint, $args, $post_id, $meta_name );
}

/**
* Force fetch stats from WPCOM, and update cache if needed.
*
* @param string $endpoint The stats endpoint.
* @param array $args The query arguments.
* @param int $post_id The post ID.
* @param string $meta_name The meta name.
*
* @return array|WP_Error
*/
protected function refresh_post_stats_cache( $endpoint, $args, $post_id, $meta_name ) {
$wpcom_stats = $this->fetch_remote_stats( $endpoint, $args );
update_post_meta( $post_id, $meta_name, array( time() => $wpcom_stats ) );

// Don't write error or empty results to cache.
if ( ! is_wp_error( $wpcom_stats ) && ! empty( $wpcom_stats ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would lean to caching even if it's an error, so that we don't put too much pressure on the backend when something goes wrong. However, we need to make sure the data expires no matter it's an error or not. What do you think?

Copy link
Contributor Author

@dognose24 dognose24 Dec 9, 2025

Choose a reason for hiding this comment

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

Yeah, that's also what I thought about as an alternative. We can always respect the cache for 5 minutes, regardless of whether it was an error or invalid data. That means even if the data is incorrect, it would last at most 5 minutes, wouldn't 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.

Updated in 4ba2b0e.

update_post_meta( $post_id, $meta_name, array( time() => $wpcom_stats ) );
}
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

This creates an inconsistency with the fetch_stats method (lines 445-484), which caches both errors and successful responses (see line 466 and 481). The fetch_stats method caches WP_Error objects with the comment "WP_Error or string (JSON encoded object)" on line 454.

Consider aligning the caching behavior between both methods. If errors and empty results should not be cached, the same logic should apply to fetch_stats. Otherwise, if caching errors is intentional (e.g., to prevent repeated failed API calls), both methods should follow the same pattern.

Copilot uses AI. Check for mistakes.

return $wpcom_stats;
}
Expand Down
Loading