Description
Symfony version(s) affected
^5.2
Description
This is a bug I've been trying to track for more than a year now, since it happens only occasionally. In the beginning I thought this was an issue with our SMTP server (you will see why below), but I am finally able to pin it down.
We occasionally send a large number (>200) transactional e-mails containing a PDF that we attach from our cdn:
$email = (new TemplatedEmail())
->...
foreach ($pdfUrls as $url) {
$email->attach(fopen($url, 'r'), $generatedName.'.pdf', 'application/pdf');
}
$this->mailer->send($email);
Out of, say 250, emails we occasionally get a very small percentage (e.g. 4/250) that fail and go to failure transport.
When we inspect the first of the failed messages, we see that attachment->body is false. Apparently, this is the problem. How come ->attach method proceeds forward when fopen returns false?
Now, this is the smaller issue. We can probably solve that by retrying 5 times to get the file with fopen (maybe there is an issue with our CDN, throttling, etc.)
The bigger issue is that this situation apparently crashes the whole SmtpTransport, as we get the following error immediately after:
Email transport "Symfony\Component\Mailer\Transport\Smtp\SmtpTransport" stopped
And it crashes in such a way that it somehow breaks the smtp server connection. The next message in the queue fails as well with Connection timeout. We checked the SMTP server logs (it is our own) and apparently symfony sends unexpected data (e.g., starting a new message w/out properly closing the previous transaction; not really sure, e-mail in general is blackbox for most).
So, the result is the problematic email fails and it also breaks the next one in the queue. We know that because a side issue is that the body => false message fails every time it is retried (normal, as the message in the queue holds the same data). I don't think the message should go to the queue at all with attachment->body->false, while the next in queue, which initially failed, works fine on retry.
Any thoughts or suggestions?
How to reproduce
Try sending a large number (>300) e-mails with attachments from an external link with fopen();
Possible Solution
Don't just set attachment body to false, give a meaningful error where the failure occurred.
Additional Context
...
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection^ {
-elements: []
}
#initialized: false
}
-photo: null
},
"content" => "concrete content",
"notificationAddonBusiness" => "bla bla",
"notificationAddonCompany" => """
bla bla
"""
]
-text: "bla bla bla"
-textCharset: "utf-8"
-html: null
-htmlCharset: null
-attachments: [
[
"body" => false,
"name" => "9000004479.pdf",
"content-type" => "application/pdf",
"inline" => false
]
]
...
See how attachment body is false.