You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update the scheduler system so that if an entire batch fails to send, including all fallbacks, the error is sent to relevant admins. Only errors which do not prevent email sending can be sent.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
After a batch exhausts all three send attempts (worker + fallbacks) and every log in the batch has status email_failed with _send_attempts >= MAX_ATTEMPTS, an admin-facing error email is sent exactly once for that batch to Site Kit admins (users with Permissions::MANAGE_OPTIONS), provided the failure reason is sendable.
Sendable failures are those whose category_id (stored in META_ERROR_DETAILS > error_data) is notsending_error. This includes:
Non-sendable: category_id === sending_error (wp_mail / mail transport failures from Track Email Sending and generic Server Errors #11861) must not trigger the admin email, as the email delivery mechanism itself is broken.
If any log in the batch was sent successfully (email_sent status), no admin error email is sent for that batch.
The admin email uses the existing error-email template with title and description set based on the error type in PUE Errors spreadsheet.
Error emails are recorded via a new META_ADMIN_NOTIFIED post meta flag on the batch's first log, preventing duplicate sends for the same batch failure.
Query all post IDs in the batch via Email_Log_Batch_Query.
Return early if any log has email_sent status, or any failed log has _send_attempts < MAX_ATTEMPTS using is_batch_all_failed.
Return early if META_ADMIN_NOTIFIED is already set on the first log in the batch (prevents duplicate sends) using is_batch_admin_notified.
Extract META_ERROR_DETAILS from the first failed log, decode JSON, and read category_id from error_data.[first_error_code].category_id.
Return early (do nothing) if category_id === 'sending_error' - the mail system is broken, so admin email cannot be sent.
Map category_id to a human-readable failure description via Content_Map::get_body() using category-keyed title copy built from copy below in the PUE Errors spreadsheet.
Resolve admin recipients: get_users( array( 'capability' => PERMISSIONS::MANAGE_OPTIONS ) ); dedupe email addresses; return early if none.
Extract META_REPORT_REFERENCE_DATES from the first log via Email_Log::get_date_range_from_log() and META_REPORT_FREQUENCY for the batch context.
Build the template data array matching the error-email template contract: subject, preheader, site.domain, site.url, title, body (array of paragraphs), primary_call_to_action, footer.
Create an Email_Template_Renderer( null ) (no sections map needed) and call render( 'error-email', $template_data ) for HTML and render_text( 'error-email', $template_data ) for plain text.
Send via Email::send() to all resolved admin addresses with both HTML and plain text content.
On success or failure, set META_ADMIN_NOTIFIED to 1 using mark_batch_admin_notified.
Add is_batch_all_failed( string $batch_id ): bool - returns true only when every log in the batch has email_failed status and _send_attempts >= MAX_ATTEMPTS, and no log has email_sent status.
Add is_batch_admin_notified( string $batch_id ): bool - checks if META_ADMIN_NOTIFIED is set on the first log in the batch.
Add mark_batch_admin_notified( string $batch_id ): void - sets META_ADMIN_NOTIFIED on the first log in the batch.
Accept Batch_Error_Notifier as a new constructor dependency.
In handle_fallback_action(), when $this->batch_query->is_complete( $batch_id ) returns true, call $this->batch_error_notifier->maybe_notify( $batch_id, $frequency )before the early return.
Accept Batch_Error_Notifier as a new constructor dependency.
In handle_callback_action(), after process_pending_logs() completes, check $this->batch_query->is_complete( $batch_id ) and if true, call $this->batch_error_notifier->maybe_notify( $batch_id, $frequency ).
Test: after processing, if batch becomes complete, maybe_notify() is called.
Test: if batch still has pending logs, notifier is not called.
QA Brief
Install the new tester plugin (@benbowler will share in Slack)
Test each error type in the PUE Errors spreadsheet and confirm the emails are received correctly by all authenticated admins and the copy and links match the spreadsheet.
Changelog entry
Send emails to site admins when entire batches of emails fail to send.
Feature Description
Update the scheduler system so that if an entire batch fails to send, including all fallbacks, the error is sent to relevant admins. Only errors which do not prevent email sending can be sent.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
email_failedwith_send_attempts>=MAX_ATTEMPTS, an admin-facing error email is sent exactly once for that batch to Site Kit admins (users withPermissions::MANAGE_OPTIONS), provided the failure reason is sendable.category_id(stored inMETA_ERROR_DETAILS>error_data) is notsending_error. This includes:permissions_error- permissions revoked / insufficient access (from Track Module reporting errors within Email Reporting #12110)report_error- API data retrieval failures beyond permissions (from Track Module reporting errors within Email Reporting #12110)null/ absentcategory_id- generic server errors such as invalid user, invalid date range, render failures (from Track Email Sending and generic Server Errors #11861)category_id===sending_error(wp_mail / mail transport failures from Track Email Sending and generic Server Errors #11861) must not trigger the admin email, as the email delivery mechanism itself is broken.email_sentstatus), no admin error email is sent for that batch.error-emailtemplate with title and description set based on the error type in PUE Errors spreadsheet.META_ADMIN_NOTIFIEDpost meta flag on the batch's first log, preventing duplicate sends for the same batch failure.Implementation Brief
Backend
Create file
includes/Core/Email_Reporting/Batch_Error_Notifier.phpEmail_Log_Batch_Query,Email(sender), andContext(for site URL/domain).maybe_notify( string $batch_id, string $frequency )method:Email_Log_Batch_Query.email_sentstatus, or any failed log has_send_attempts<MAX_ATTEMPTSusingis_batch_all_failed.META_ADMIN_NOTIFIEDis already set on the first log in the batch (prevents duplicate sends) usingis_batch_admin_notified.META_ERROR_DETAILSfrom the first failed log, decode JSON, and readcategory_idfromerror_data.[first_error_code].category_id.category_id === 'sending_error'- the mail system is broken, so admin email cannot be sent.category_idto a human-readable failure description viaContent_Map::get_body()using category-keyed title copy built from copy below in the PUE Errors spreadsheet.get_users( array( 'capability' => PERMISSIONS::MANAGE_OPTIONS ) ); dedupe email addresses; return early if none.META_REPORT_REFERENCE_DATESfrom the first log viaEmail_Log::get_date_range_from_log()andMETA_REPORT_FREQUENCYfor the batch context.error-emailtemplate contract:subject,preheader,site.domain,site.url,title,body(array of paragraphs),primary_call_to_action,footer.Email_Template_Renderer( null )(no sections map needed) and callrender( 'error-email', $template_data )for HTML andrender_text( 'error-email', $template_data )for plain text.Email::send()to all resolved admin addresses with both HTML and plain text content.META_ADMIN_NOTIFIEDto1usingmark_batch_admin_notified.Update file
includes/Core/Email_Reporting/Email_Log.phpMETA_ADMIN_NOTIFIED = '_admin_notified'.register_post_meta()withtype => 'string',single => true, using the existingmeta_auth_callback.Update file
includes/Core/Email_Reporting/Email_Log_Batch_Query.phpis_batch_all_failed( string $batch_id ): bool- returnstrueonly when every log in the batch hasemail_failedstatus and_send_attempts >= MAX_ATTEMPTS, and no log hasemail_sentstatus.is_batch_admin_notified( string $batch_id ): bool- checks ifMETA_ADMIN_NOTIFIEDis set on the first log in the batch.mark_batch_admin_notified( string $batch_id ): void- setsMETA_ADMIN_NOTIFIEDon the first log in the batch.Update file
includes/Core/Email_Reporting/Fallback_Task.phpBatch_Error_Notifieras a new constructor dependency.handle_fallback_action(), when$this->batch_query->is_complete( $batch_id )returnstrue, call$this->batch_error_notifier->maybe_notify( $batch_id, $frequency )before the early return.Update file
includes/Core/Email_Reporting/Worker_Task.phpBatch_Error_Notifieras a new constructor dependency.handle_callback_action(), afterprocess_pending_logs()completes, check$this->batch_query->is_complete( $batch_id )and if true, call$this->batch_error_notifier->maybe_notify( $batch_id, $frequency ).Update file
includes/Core/Email_Reporting/Email_Reporting.phpBatch_Error_Notifierwith$this->email_log_batch_query,$email_sender, and$this->context.Worker_TaskandFallback_Taskconstructors.Update file
includes/Core/Email_Reporting/Content_Map.phpTest Coverage
tests/phpunit/integration/Core/Email_Reporting/Batch_Error_NotifierTest.php:MAX_ATTEMPTSwith a sendablecategory_id(permissions_error,report_error, or absent).category_id === 'sending_error'(non-sendable).email_sentstatus (mixed batch).META_ADMIN_NOTIFIEDis already set (duplicate prevention).META_ADMIN_NOTIFIEDafter sending.MANAGE_OPTIONScapability.tests/phpunit/integration/Core/Email_Reporting/Fallback_TaskTest.php:is_complete()returns true,maybe_notify()on the notifier is called.tests/phpunit/integration/Core/Email_Reporting/Worker_TaskTest.php:maybe_notify()is called.QA Brief
Changelog entry