6

I am having an issue with Nodemailer on Heroku and I would really appreciate your help.

A previous version of my application used to work on Heroku with no problem and when I roll back to that version, it still works fine. In the latest version of the application, I have made no changes to the code accesses Nodemailer so this doesn't really make sense to me.

The version of nodemailer is: 0.6.5

Here is the log message:

2015-02-18T04:29:57.730815+00:00 app[web.2]: POST /employer/53f44e3df4f8150200554eb7/job/ 200 32ms - 581b
2015-02-18T04:29:58.045066+00:00 app[web.2]: /app/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:918
2015-02-18T04:29:58.045069+00:00 app[web.2]:     this._xoauth2.reconnectCount = 0;
2015-02-18T04:29:58.045070+00:00 app[web.2]:                                  ^
2015-02-18T04:29:58.041300+00:00 app[web.2]: Exit callback being invoked
2015-02-18T04:29:58.045072+00:00 app[web.2]: TypeError: Cannot assign to read only property 'reconnectCount' of false
2015-02-18T04:29:58.045073+00:00 app[web.2]:     at SMTPClient._actionAUTHComplete (/app/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:918:34)
2015-02-18T04:29:58.045075+00:00 app[web.2]:     at SMTPClient._onData (/app/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:352:29)
2015-02-18T04:29:58.045076+00:00 app[web.2]:     at TLSSocket.emit (events.js:107:17)
2015-02-18T04:29:58.045078+00:00 app[web.2]:     at readableAddChunk (_stream_readable.js:163:16)
2015-02-18T04:29:58.045079+00:00 app[web.2]:     at TLSSocket.Readable.push (_stream_readable.js:126:10)
2015-02-18T04:29:58.045080+00:00 app[web.2]:     at TCP.onread (net.js:529:20)
2015-02-18T04:29:58.769185+00:00 heroku[web.2]: Process exited with status 1
2015-02-18T04:29:58.780771+00:00 heroku[web.2]: State changed from up to crashed
2015-02-18T04:29:58.780771+00:00 heroku[web.2]: State changed from crashed to starting
2015-02-18T04:30:00.371578+00:00 heroku[web.2]: Starting process with command `node app.js`
2015-02-18T04:30:01.904015+00:00 app[web.2]: Detected 512 MB available memory, 512 MB limit per process (WEB_MEMORY)
2015-02-18T04:30:01.904115+00:00 app[web.2]: Recommending WEB_CONCURRENCY=1
2015-02-18T04:30:02.288471+00:00 app[web.2]: Failed to load c++ bson extension, using pure JS version
2015-02-18T04:30:02.652326+00:00 app[web.2]: Started in PROD mode
2015-02-18T04:30:02.815284+00:00 app[web.2]: Express server listening on port 9622
2015-02-18T04:30:03.291115+00:00 heroku[web.2]: State changed from starting to up

We can see that it is failing on line 918 of 'client.js' with the error of:

TypeError: Cannot assign to read only property 'reconnectCount' of false.

Why would it be trying to assign 'false' to 'reconnectCount'?

My code is really simple:

app.locals.smtpTransport = nodemailer.createTransport('SMTP', { service: 'Gmail', auth: { user: "example@gmail.com", pass: "pass123" } }); I then use the code to send mail like:

req.app.locals.smtpTransport.sendMail( ......

This code works on my staging instance of Heroku so that doesn't make sense to me.

I have logged a support request with Heroku and any guidance that you can provide I will pass onto them.

Thanks so much for your help.

Gaj
  • 293
  • 2
  • 11

2 Answers2

11

I just got the following response back from Nodemailer:

You are probably running Nodemailer in iojs. Only the latest version of Nodemailer is suported in node 0.12 and iojs, so you should either upgrade or fix the line 918 yourself like this:

if(this._xoauth2){
    this._xoauth2.reconnectCount = 0;
}

Setting properties to boolean values was allowed in ES5 but iojs runs ES6 and trying to set a property in ES6 strict mode throws an error.

I think I have fixed this by by explicitly setting the node.js version in my package file to an older version that uses ES5.

This has fixed my problem. Lesson learned is to always set the nodejs version in the package file otherwise Heroku uses the latest version and it may be incompatible with your modules.

Many thanks to Nodemailer, they got back to me super quick with a great response.

Hopefully this will help someone else.

Thanks.

Gaj
  • 293
  • 2
  • 11
  • 1
    This is useful to know for developers who install Ghost blogging platform. Once you upgrade Nodejs to version 0.12, supposing you're using a pre 0.4 version of Ghost, you'll get this error in the following file at this line number depending on your Ghost version number and nodemailer version: `ghost/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:828`. I edited this line accordingly and my pre v.0.4 Ghost blog can now send emails with Nodejs v.0.12. – surfbuds Sep 30 '15 at 05:38
  • This worked perfectly for me after upgrading to the latest version. – Mike B Mar 20 '18 at 10:34
8

I'm working with meteor on an ubuntu install and I was getting similar errors after upgrading to Node.js v12.0 and installing Meteor's accounts-password module.

Turned out, since Meteor has not yet begun development on compatibility with Node.js v12.0, the new binaries installed with Node on my server were not compatible with the binaries bundled with my deployment so I was getting similar errors. In this case, the problem was not with Nodemailer but with simplesmtp.

As suggested here, the solution was to remove the bundled version and use npm to install a server-local version.

So in my deployment script, I added the following lines after I built the bundle.

cd bundle/programs/server/
sudo rm -R ./npm/npm-bcrypt/node_modules/bcrypt
sudo npm install bcrypt
sudo rm -R ./npm/email/node_modules/simplesmtp
sudo npm install simplesmtp

This is easier than modifying the source, especially if you have a scripted deployment.

Community
  • 1
  • 1
Wes Modes
  • 2,024
  • 2
  • 22
  • 40
  • 1
    Note that in Meteor 1.3 (and potentially above) the file structure has changed and `email` now resides in `bundle/programs/server/npm/node_modules/meteor/email`. – neo post modern Apr 16 '16 at 10:53
  • npm-bcrypt has also been moved. While it's easy to find and remove I don't know where I should reinstall it... – Zach Smith May 17 '16 at 06:08