Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
On a particular site I'm using the latest release of SMTP module to send emails and Queue Mail to queue them for sending. When everything's working fine it's great. However, I've noticed that if the message fails to be delivered that it logs this fact in watchog bug does not add the message back into the queue to be tried again later, instead the message just disappears. This obviously goes against one of the reasons to use a queue in the first place. I'm marking this as critical as it involves data loss, i.e. the emails disappear.
Comment | File | Size | Author |
---|---|---|---|
#6 | queue_mail-keep_failures_in_queue-2442467-6-D7.patch | 1.52 KB | sinn |
| |||
#4 | keep_failures_in_queue-2442467.patch | 1.44 KB | jacobischwartz |
Comments
Comment #1
DamienMcKennaClosed a duplicate: #2154395: Create hook to allow other modules to respond to sent mails (both successful or failed)
Comment #2
Steven Jones CreditAttribution: Steven Jones commentedSo i think that all we need to do is throw an exception if the mail fails to send, and then I think that the Drupal queue system should not remove the item from the queue.
Comment #3
jacobischwartz CreditAttribution: jacobischwartz commentedDid you guys find a good solution to this?
Comment #4
jacobischwartz CreditAttribution: jacobischwartz commentedI've gone ahead and built a fix.
Attached is a patch that causes the queue worker to throw an exception. I've also added a try-catch around the drush operation, so that the queue can progress and Drupal can exit gracefully (which is the workflow in drupal_cron_run()).
A bit more information:
- The smtp module will only pass a send failure back to this module if you have that module's queue turned off. So if you're using the smtp module's queue, this module won't know about the failure and won't be able to re-process it.
- The Drupal queue system uses a lease lock on items when claiming them for worker functions. By throwing an exception, we are preventing the item from being deleted from the queue (either via cron run or drush). The item's lease then expires. At the next Drupal cron run, the expiry is cleared. Once the expiry is cleared, the queue claim method will pick up the item for processing again. So basically the item will be re-processed AFTER the next Drupal cron run, then AT the next queue processing moment. That could be either a cron run or a drush call.
Comment #5
amonteroAbout the
watchdog_exception
call, from the watchdog() docs:Minor comment text nitpick:
// Log errors and throw exception so that failed item remains in queue.
Otherwise, I'm +1 on the idea. Throwing an exception in case of error is the way to go in queue worker code. If not done like this, failed messages simply get deleted from queue as if they were successfully processed, thus getting lost forever.
Comment #6
sinn CreditAttribution: sinn at Adyax commentedUpdated comment #4
Comment #7
Steven Jones CreditAttribution: Steven Jones at ComputerMinds commented@sinn any chance you can incorporate the suggestion in #5 into the patch?
Comment #8
sinn CreditAttribution: sinn at Adyax commentedActually I did it.
Comment #9
sinn CreditAttribution: sinn at Adyax commentedComment #11
sinn CreditAttribution: sinn at Adyax commented