swiftmailer, ovh, INTERMITTEND Expected response code 250 but got code "", with message "" - symfony

This very same problem already has some similar entries in stackoverflow, but none of them ever had any answers/solutions apart from some more basic coding hints.
I am using Symfony2 framework+swiftmailer on an OVH shared server and when sending a mail through the user interface (of the web page) I am getting intermittently the http error: Expected response code 250 but got code "", with message "".
With some googling for this error I understand that the server receives an order to read a mail, which is empty, so that it does not know what to do with an empty mail (no to, no from, no body, ...NULL in a way).
I am not sending mass mail, only one after one.
The intermittent character of this makes debugging awkward as anytime you make a little tweak and it seems to work, you can not not be sure if the last tweak fixed it or if "it" simply decided to "wake up" again.
So far all my little counter tweaks ended up that the empty smtp return from the server popped up again after some hours/some days. Because of this I am still hiding the site behind a htaccess so that traffic is extremely small (it is basically only myself).
Intermittence is around 5 to 10% of all mails. If that empty error appears then for 95% of any tweak in the code the error remains. There is only one "tweak" which so far made the error go away "reliably": reloading the parameter.yml, but since there is 5% of cases where I tweaked something else and the error also went away I can't be sure if I should concentrate on the parameters. But again, the error will come back after hours/days in any case. The whole looks more like a server-cache/CDM issue.
Here's the details of code to be known (since it is working "most of times", the code as such is probably clean.. but one never knows).
parameters.yml:
mailer_transport: smtp
mailer_host: ssl0.ovh.net
mailer_port: 465
# OR alternatively (gives the same result) :
# mailer_host: ns0.ovh.net
# mailer_port: 587
mailer_user: *********
mailer_password: **********
config.yml:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
port: "%mailer_port%"
# and also :
fos_user :
from_email:
address: ********* (same as mailer_user)
sender_name: ***********
controllerXYZ:
$mailer=$this->get('mailer');
$params=$form->getData();
$subject=$params['subject'];
$body=$params['body'];
$userManager=$this->get('fos_user.user_manager');
$toUser=$userManager->findUserBy(array('username'=>$comment->getAuthor()));
$to=$toUser->getEmail();
$from=$this->getUser()->getEmail();
$message= \Swift_Message::newinstance()
->setSubject($subject)
->setBody($body)
->setFrom($from)
->setTo($to);
$mailer->send($message);
I "tweaked" with sleep(x), with \vendor\SM\SM\lib\classes\Swift\Transport, file=EsmtpTransport.php timeout, some try/catches, ports/server id's, spool but always got the error back after a while. All the tweaks are set back to "standard" of course.
I could try another mailer (phpmail), but since it seems OVH/CDM/server related I am worried to get the same thing again.
Alternatively I could also try to make the error appear "on purpose" to get a hint; but I could not even get that done.
GIVE ME PLEASE A DIRECTION TO TRY OUT!

Over three months I did not find the cause of the intermittent problem. Therefore I implemented a work around. Although I am not really satisfied, it allowed me to render the website public.
Here is the try and catch workaround, ugly but working since 1 month (with Symphony2 classes):
$message= \Swift_Message::newinstance()
->setSubject($subject)
->setBody($body)
->setFrom($from)
->setTo($to);
try
{
try
{
$mailer->send($message,$failure);
$translatedText1 = $this->get('translator')->trans('flash.mail.sent1');
$translatedText2 = $this->get('translator')->trans('flash.mail.sent2');
$messageOut=$translatedText1.$mailarticle->getAuthor().$translatedText2;
}
catch(\Exception $e)
{
mail($to,$subject,$body,'From: '.$from);
$translatedText1 = $this->get('translator')->trans('flash.mail.std1');
$translatedText2 = $this->get('translator')->trans('flash.mail.std2');
$messageOut=$translatedText1.$mailarticle->getAuthor().$translatedText2;
}
}
catch(\Exception $e)
{
$translatedText1 = $this->get('translator')->trans('flash.mail.except1');
$translatedText2 = $this->get('translator')->trans('flash.mail.except2');
$messageOut=$translatedText1.$e->getMessage().$translatedText2.$failure;
}
The $translatedText1/2 and $messageout portions are simply texts of the messages shown to a user after having sent a mail. The object->trans() is a text functionality of Symfony.
Strangely that albeit I did not receive a single answer, the question received some credit points.
Still, as the above solution is not solving the root cause - anyone answer addressing the cause will still very much appreciated!

Here is my OVH plan with shared e-mail config.yml (values are of course parameters, copied here for more visibility):
# Swiftmailer Configuration
swiftmailer:
transport: mail
auth_mode: login
host: ssl0.ovh.net
port: 587
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
Other transports I tried before: sendmail, smtp.
The strange thing is: once I set the transport config to mail, I noticed a delay before Symfony used the chosen Swift_Transport implementation. May I say I was in dev mode?
So, my advice is: set the config, go and have a coffee, enjoy.

i got the same problem, ovh support told me it's not possible to use smtp with shared server. The solution is to use transport: sendmail or transport: mail for older version of swiftmailer (deprecated now)

Related

Mailhog, Trapmailer and gmail via symfony

I got some trouble with mails generation on my Symfony app :
I use docker
when I use Gmail to send emails :
MAILER_URL=gmail://MyAddress#gmail.com:MyPw#localhost
everything works fine
but as soon as I try to intercept these mails :
======================
Like this for mailtrap
MAILER_DSN=smtp://b3f077aeceaeb6:8792a1811dd8ef#smtp.mailtrap.io:2525?encryption=tls&auth_mode=login
MAILER_URL=smtp://smtp.mailtrap.io:25&auth_mode=login&username=b3f077aeceaeb6&password=8792a1811dd8ef
or like this for mailHog
MAILER_DSN=smtp://localhost:1025
MAILER_URL="smtp://mailhog:1025?encryption=ssl&auth_mode=login&username=null&password=null"
my docker-compose.yml looks like this :
mailhog:
container_name: mailhog
restart: always
image: mailhog/mailhog:latest
ports:
-'8025:8025'
-'1025:1025'
Does anyone know how to see the mails displayed in mailhog? mailhog page is loaded correctly but nothing shows in it.
The function sending the mail is entered, so this must be a configuration problem in my opinion
Based on your post, I had a similar problem with mailhog and SwiftMailer for Symfony.
I ended up using the smtp for both MAILER_DSN and MAILER_URL as follows
MAILER_DSN=smtp://localhost:1025
MAILER_URL="smtp://localhost:1025?auth_mode=login"
As you can see the trick was to remove encryption=ssl as the mailhog does not supports it and the username=null&password=null as the software sends it as literal string "null".
Besides, in my swiftmailer.yaml and mailer.yaml I have this very simple configuration
# swiftmailer.yaml
swiftmailer:
url: '%env(MAILER_URL)%'
spool: { type: 'memory' }
# mailer.yaml
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
You need to narrow down the issue.
1. Can you send you an email via telnet or openssl (in case of STARTTLS)?
Via telnet: https://mediatemple.net/community/products/dv/204404584/sending-or-viewing-emails-using-telnet
Via OpenSSL: https://www.stevenrombauts.be/2018/12/test-smtp-with-telnet-or-openssl/
Go through the tutorial (or any on this topic) and make sure your MAILER_URL is correct (including credentials, port, etc). The last time I had some issue with email, turned out that the firewall was blocking me.
Don't be quick to rule out networking issues.
2. Once you confirmed that you can send an email via Telnet/OpenSSL:
you need to go level up and try to configure the URL in Symfony and attempt sending via swiftmailer:send command. This may reveal some odd configuration issues in Symfony and you can fix them accordingly
3. Repeat (1) and (2) but from Docker container.
Just exec into Docker and do it all over again. This may reveal some issues in Docker network configuration, which you can fix.
Please update your question with more findings and we could probably help you further...

Symfony 3.4 and Swiftmailer - is it possible to send emails immediately/without spool?

I want emails sent by my web app to be sent immediately. However, no matter what I try to do, emails keep getting spooled by the system. My app/config/config.yml:
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
When I add spool: { type: memory } to the config, the spool isn't sent upon kernel termination as it says in the docs. Is there a way to force immediate delivery?
If you don't specify something else in the config, mails are sent immediatly and not spooled.
You can check it out on the guide
The default behavior of the Symfony mailer is to send the email messages immediately. You may, however, want to avoid the performance hit of the communication to the email server, which could cause the user to wait for the next page to load while the email is sending.
Simply omit the spool part in the configuration and it should be fine.
If the email does not be sent out, maybe, you have errors in the email server or somewhere else not related directly with Swift mailer.
Had to clear the cache.
$ bin/console cache:clear --env=prod

Symfony 3 : Swiftmailer won't send email from website while working with the swiftmailer:email:send command

I face a problem I don't understand.
I use SwiftMailer to send emails (ex : registration confirmation) from a website using the Mailjet SMTP. Mails are not sent.
The Symfony profiler says that 1 mail is spooled when I create a user account, but it is never sent.
php bin/console swiftmailer:spool:send returns 0 emails sent. I tried memory and file spools.
When using the php bin/console swiftmailer:email :send, mails are correctly sent (mails have the mailjet headers and they are in the mailjet sent mails interface).
When I'm trying the OVH SMTP, mails are correcly sent both from the application and cli command, so the problem seems to be a SwiftMailer misconfiguration.
Here is my setup :
app/config/config.yml
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host_prod%"
port: "%mailer_port_prod%"
encryption:"%mailer_encryption_prod%"
username: "%mailer_user_prod%"
password: "%mailer_password_prod%"
spool: { type: memory }
app/config/parameters.yml
mailer_transport: smtp
mailer_host_prod: in-v3.mailjet.com
mailer_port_prod: 587
mailer_encryption_prod: tls
mailer_user_prod: api_key
mailer_password_prod: api_secret
mailer_host_ovh: ssl0.ovh.net
mailer_port_ovh: 465
mailer_encryption_ovh: ssl
mailer_user_ovh: email
mailer_password_ovh: password
It works for me. I had the same issue, but I had an exit after sending the email and in this case, the spool doesn't send the email, because the kernel does not end properly. If you remove spool: { type: memory }, then it will send the email.
To send the email properly with spool, then you need to end the kernel properly.
Did your request finish without any errors when creating the message ?
On https://symfony.com/doc/current/email/spool.html : "This means the email only gets sent if the whole request got executed without any unhandled exception or any errors."
Finally, it was the sender's email who was wrong. I forgot to update it after going prod.
At this moment, Mailjet successfuly receive the email but put it in queue and don't send it. On Symfony side, it is a success.

LogicException: Missing default data in Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector

Getting this exception in Symfony 2.5.5 with Swiftmailer 5.3.0. I'm following the cookbook example exactly. The error is thrown when calling MessageDataCollector#getMessages():
// Check that an e-mail was sent
$this->assertEquals(1, $mailCollector->getMessageCount());
$collectedMessages = $mailCollector->getMessages();
$message = $collectedMessages[0];
The message count assertion is also failing with a value of zero.
As far as I can tell the collector is failing to do any actual collecting in the action. Any ideas?
I encountered the same problem after I applied kriswallsmith's test optimization trick. I could see the result of the mail sending in the web profiler when running the development version, but couldn't get the data in the testing environment.
After applying Kris' trick I noticed that the swiftmailer.mailer.default.plugin.messagelogger service was not registered with the container during the test, so the collect() method of the MessageDataCollector class did not log the data for the mail sending. This is why it wasn't possible to retrieve information from the swiftmailer collector.
The solution is either not to overrride the initializeContainer() method in AppKernel.php or to override it, but making sure messagelogger service is available for test cases that send mails.
#codeBetyar is right - problem occurs when swiftmailer.mailer.default.plugin.messagelogger is not registered in container.
But instead of getting rid of the optimization trick - you just need to update swiftmailer configuration for test environment
swiftmailer:
logging: true
The thing is logging config value by default equals to kernel.debug (https://github.com/symfony/swiftmailer-bundle/blob/master/DependencyInjection/Configuration.php#L121) which (thanks to the trick) is true for the first test request, and false - for all following requests.
Above config forces logger being registered.
In my case I had multiple mailers in the config.yml file and the same problem was due to a missing parameter in the getMessages() call.
My config.yml file:
swiftmailer:
default_mailer: default_mailer
mailers:
default_mailer:
# some configuration
another_mailer:
# some configuration
The correct call was:
$mailCollector = $this->client->getProfile()->getCollector('swiftmailer');
$collectedMessages = $mailCollector->getMessages('default_mailer'); // please note the 'default_mailer' argument
$messagesCount = $mailCollector->getMessageCount('default_mailer')
My problem was that apparently if there are no messages to retrieve (or perhaps no swiftmailer instantiation in the code being tested?), the call to getMessages() returns this obtuse error. So I bypassed the problem by testing for getMessageCount() first.

FOSUserBundle sending bad confirmation links

1 or 2% of users registering seem to get no confirmation email or they get a bad token appended to the confirmation link in the email. I can't determine why or where this wrong token comes from. It doesn't look like a truncated version of the correct one. It's totally different. Clicking it yields a 404 response.
I am not overriding the RegistrationController.
Could it be the mailer settings?
swiftmailer:
~
spool: { type: memory }
The only other changes I've made were in validation of a few custom fields.
registration:
form:
type: acme_user_registration
validation_groups: [MyRegistration]
confirmation:
enabled: true
Any ideas what's going on?
Thanks.
I found a problem while viewing a confirmation email in outlook.com. I turns out that outlook.com is 'previewing' the link to show some expanded metadata in the email message. This has the side effect of enabling the user and deleting the token. Once the user actually clicks the link, they get a token not found error, but their account is enabled.

Resources