Problem/Motivation

During spooling (for example via cron, drush or UI), Mailer::sendSpool keeps track of the sent emails, but doesn't store it until the very end of the process. This means if anything interrupts that process, for example an exception, causes it to lose track of all the emails stats it had previously built up.

In my specific case, my error was:
TypeError: Argument 1 passed to Drupal\Core\Session\AccountSwitcher::switchTo() must implement interface Drupal\Core\Session\AccountInterface, null given, called in /var/www/html/web/modules/contrib/simplenews/src/Mail/MailEntity.php on line 256 in Drupal\Core\Session\AccountSwitcher->switchTo() (line 58 of /var/www/html/web/core/lib/Drupal/Core/Session/AccountSwitcher.php).

Proposed resolution

Mailer::sendMail should be as aggressive as possible at catching errors in the sending process without falling over. I would suggest that it has a catch (\Throwable $throwable) { ... } to handle as many possible scenarios.

It seems a reasonable assumption that it will have failed to send, so should be tracked as skipped, and should be treated as an error. It would also make sense to log these errors so that they're not simply silenced.

Remaining tasks

Do it!

User interface changes

None.

API changes

Fewer unhandled errors causing problems.

Data model changes

None.

Release notes snippet

Mailer::sendMail has been made more resilient to errors in the mail building and sending process by catching all throwable errors and exceptions, logging them and treating the email as a permanent failure.

Comments

andrewbelcher created an issue. See original summary.

andrewbelcher’s picture

StatusFileSize
new1.03 KB

Here's a patch that implements it! Not sure if we want to add some test coverage in for this?

This should apply to 8.x-1.x as well. I'm not sure if you're happy porting bug fixes back to 8.x-1.x if the work is already done, but it'd be really handy until we've got the space to update to 2.x.

andrewbelcher’s picture

Assigned: andrewbelcher » Unassigned
Status: Active » Needs review
andrewbelcher’s picture

Ok - 8.x-1.x failed to apply, so here is a patch for 8.x-1.x.

Status: Needs review » Needs work

The last submitted patch, 4: 3075506-4-catch_throwables_in_mailer-8.x-1.x.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

andrewbelcher’s picture

Status: Needs work » Needs review
adamps’s picture

Priority: Major » Normal
Status: Needs review » Needs work
Issue tags: +Needs tests, +Needs issue summary update

Thanks for posting a patch @andrewbelcher.

I am not a big fan of code that catches all exceptions as it can obscure the underlying problem. We should understand how the exception arises and investigate if it is caused by a bug somewhere in the code. Please can you update the issue summary to describe how to produce the error?

Before this patch could be committed there would also need to be a matching test.

tr’s picture

Additionally, this patch ADDS 4 coding standards violations. If the patch is to be committed, it should adhere to Drupal coding standards.