sighmon/mjml-rails

Blank emails on production

Closed this issue · 14 comments

Hi,

can't find any solutions so far for this, hope you could have some ideas about it.
Our mjml powered emails work perfectly when we use deliver_later, come out empty when we use deliver_now.
If we try the same methods from console, everything works.

Everything works fine in development too, I thought it could be something related to envs, but I could find any references of envs in the gem, am I wrong?
Thanks

Hi @apuntovanini, I haven't used deliver_now, I still use deliver.

The only other time I've had an empty output was when I had a syntax error in my .mjml file resulting from some bad code I wrote in a partial.

Any chance you could throw together a bare bones app to show it failing on Heroku or similar?

Hi @sighmon,

unfortunately I can't work on a bare bones app, but I can leave some insights in case someone has the same problems. What's really strange is that deliver and deliver_now are equivalent in 4.2 https://apidock.com/rails/ActionMailer/MessageDelivery/deliver

As I said, emails work just fine with deliver_later, same template and same data, so I think it's not a syntax error with mjml. We thought it was something related to mjml version installed in our servers, but it's not the case.

We ran out of ideas, we made it work using delayed emails (deliver_later), but still can't understand why this is happening. If no one has the same problem, I think we should dig further into our stack, what do you think? Thanks a lot for the feedback

@apuntovanini that's strange that deliver and deliver_now are equivalent but show different behaviour for each of us. This leads me to believe there's something else interacting with your setup.

Glad you've got a workaround, and yes if it does come up again with anyone else we can investigate trying to setup a bare bones app to replicate the problem.

pjar commented

@sighmon We have probably a related issue. We use Rails 3 and we send emails with sidekiq background job. Most of the emails look fine but we have more and more being sent as blank. We host the app on Heroku. If that happens we are able to just retrigger email delivery from heroku console and they are sent fine - with content.

Not sure yet how this gem works but it seems that sometimes lib is not able to use the binary to process contents and it might be returning some nil which causes genaration of blank emails.

We are trying to figure it out currently.

We use 2.4.0 version of the gem.

pjar commented

@sighmon Since render method is rescuing everything https://github.com/sighmon/mjml-rails/blob/master/lib/mjml/parser.rb#L21 we will always get empty string on any error. We will probably make a fork to not escape things and raise to see what's the error in such cases.

pjar commented

@sighmon so the error causing blank contents seems to be this one: Errno::ENOENT: No such file or directory @ rb_sysopen - /tmp/out_DOLDRPYD.html. Probably easy workaround is just to repeat rendering. I'm still not sure why this happens

@pjar so is this less related to the gem and more related to MJML itself?

pjar commented

@sighmon blank emails are related directly to how render method handles exceptions. Those exceptions though, are probably not related to the gem. It might be that MJML binary somehow returns proper exit code just before the temp output file is available. I've monkey patched the parser method to retry itself when an exception happens and made a simple test that showed it was enough. I'll try to create a PR sometime later today.

ayb commented

Just wanted to ask if anyone had any insight on this?

We're running into a similar issue but the opposite - using Rails 5.1 we are able to send fine with deliver_now but deliver_later is running into issues where our Resque environment can't find the MJML binary file. It will either blow up with that error or send blank e-mails.

@ayb if you'd like to create a Rails skeleton project with tests that show it breaking that'd be great - then we can debug as a community and fix it. :-)

nelyj commented

@sighmon @apuntovanini After many test, I found that the error (in my case) can produced because your node version is < 6.0

screenshot 2017-09-08 16 07 36

I recommend you to check your node version.

After update my node version to 8.0 my emails rendered correctly.

Also if you would like test the command, write this line of code. In other words this line of code return some like that:

mjml -r /tmp/in_OSWCMPNY.mjml -o /tmp/out_OSWCMPNY.html

Thanks a lot for this comment @nelyj, I just switched to the Debian based Ruby Docker image (after the Chromium / Chrome-driver package recently got broken in the Alpine one...) and had to realise that the Node version installed via apt-get install nodejs is version 4.

Using the method described here, ie adding curl -sL https://deb.nodesource.com/setup_8.x | bash - before apt-get solved the issue for me.

Hey, we got same problem on production.
Mails just render empty string which is from Mjml::Parser
I debug whole thing and found out that

lib/mjml/parser.rb
...
run in_tmp_file.path

returns this error:

*** Mjml::Parser::ParseError Exception: File: /var/folders/05/n5zylzb50wj55by3zqj8vd_r0000gn/T/in20180703-5846-1pfm1ay.mjml
TypeError: Cannot read property 'children' of undefined
Input file(s) failed to render

nil

EDIT
I found out that we used old syntax of MJML so I used mjml -m old_syntax_input.mjml -o new_syntax_output.mjml and now it works without any problem.

@bonekost Great you got it sorted. I had a problem with my MJML syntax too - I just had to remove <mj-container> tags.