From a914916ad804967bca1d61828b1e45f06a14bb0c Mon Sep 17 00:00:00 2001 From: David Stone Date: Tue, 24 Mar 2026 20:54:16 -0600 Subject: [PATCH] fix(membership): reset is_publishing on thrown exceptions in publish_pending_site Addresses PR #372 CodeRabbit review feedback (issue #412). The rollback that clears the pending site's 'publishing' flag previously only ran when Site::save() returned a WP_Error. If Site::save() or a downstream hook threw a Throwable (e.g. a PHP exception or Error), the pending site remained stuck in 'Creating' state and the cron/manual retry path could not recover. Wrap the Site::save() call in try/catch(\Throwable) so that both WP_Error returns and thrown exceptions reset is_publishing and return a WP_Error to the caller. --- inc/models/class-membership.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/inc/models/class-membership.php b/inc/models/class-membership.php index 35cd92032..31562f53c 100644 --- a/inc/models/class-membership.php +++ b/inc/models/class-membership.php @@ -2046,7 +2046,21 @@ public function publish_pending_site() { $pending_site->set_type('customer_owned'); - $saved = $pending_site->save(); + try { + $saved = $pending_site->save(); + } catch (\Throwable $e) { + /* + * Reset is_publishing when Site::save() or a downstream hook throws, + * so the cron/manual retry path is not stuck in "Creating" state. + * + * @since 2.4.13 + */ + $pending_site->set_publishing(false); + + $this->update_pending_site($pending_site); + + return new \WP_Error('pending_site_publish_failed', $e->getMessage()); + } if (is_wp_error($saved)) { if ($saved->get_error_code() === 'site_taken') {