Search code examples
node.jsherokuexpresssmtpnodemailer

NodeMailer Request timeout on Heroku (Mandrill, SMTP), works on localhost


I'm using nodemailer in an express / angular app and tried a few things with a basic mailer, using nodemailer. I tried using Hotmail as the service and it worked on localhost but on heroku it would constantly return 503 or Invalid Credentials even though it worked.

Second I'm trying to hook it up with my Mandrill Account, the code looks like this:

Angular (ES6):

sendEmail(form) {

var data = {
  contactName: form.name,
  contactEmail: form.email,
  comments: form.comments || null
};

var req = {
 method: 'POST',
 // url: 'http://localhost:9030/email', <- my express port
 url: location.origin + '/email',
 // url: 'https://myherokuapp.herokuapp.com/email', <- my heroku app
 headers: {
   'Content-Type': 'application/json'
 },
 data: data
};

this.$http(req)
.then((result) => {
  console.log('success is...', result);
  return result;
})
.catch((error) => {
  console.log('error is...', error);
  return error;
});

}

Express:

    var transport = nodemailer.createTransport("SMTP", {
    service: 'Mandrill', // use well known service.
    // If you are using @gmail.com address, then you don't
    // even have to define the service name
    auth: {
        user: "[email protected]",
        pass: "xxxxxxxxxxxxxxxx"
    }
});

console.log('SMTP Configured');

var message = {

    // sender info
    from: 'Sender: <' + req.body.contactEmail + '>',

    // Comma separated list of recipients
    to: '"Info:" <[email protected]>',

    // Subject of the message
    subject: 'Nodemailer is unicode friendly ✔', //

    headers: {
        'X-Laziness-level': 1000
    },

    // plaintext body
    text: "Interest\n" +
        "===========\n" +
        "\n" +
        "**How** are you?"
};

console.log('Sending Mail');
transport.sendMail(message, function(error) {
    if (error) {
        console.log('Error occured');
        console.log(error.message);
        return;
    }
    console.log('Message sent successfully!');

    // if you don't want to use this transport object anymore, uncomment following line
    transport.close(); // close the connection pool
});

I'm really stuck and it feels like a simple task, works on localhost but not on heroku. With the Mandrill SMTP when I send something in the form, I get these logs on heroku:

2015-08-24T15:12:58.800676+00:00 app[web.1]: POST /email - - ms - -
2015-08-24T15:13:15.858302+00:00 app[web.1]: { contactName: 'testing',
2015-08-24T15:13:15.858307+00:00 app[web.1]:   contactEmail: '[email protected]',
2015-08-24T15:13:15.858309+00:00 app[web.1]:   comments: 'asdfasdf' }
2015-08-24T15:13:15.858316+00:00 app[web.1]: Email params (name):testing
2015-08-24T15:13:15.858376+00:00 app[web.1]: Email params (email):[email protected]
2015-08-24T15:13:15.858417+00:00 app[web.1]: Email params (comments):asdfasdf
2015-08-24T15:13:15.858498+00:00 app[web.1]: SMTP Configured
2015-08-24T15:13:15.858537+00:00 app[web.1]: Sending Mail
2015-08-24T15:13:15.889774+00:00 app[web.1]: Message sent successfully!
2015-08-24T15:13:45.845230+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path="/email" host=secret-river-5414.herokuapp.com request_id=5c1e8378-6971-4253-86e2-a9647fc7e0d4 fwd="14.200.153.28" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0
2015-08-24T15:13:45.857582+00:00 app[web.1]: POST /email - - ms - -

Please if someone could shed some light, thanks!


Solution

  • Okay, so in case anybody else runs into this, I found it was really just a problem with the free hosting I was using. Heroku timed out my request because it took too long to complete the action, which closes the connection pool for the mailer. I noticed the email came through eventually but at a much later time.

    This was rectified by simply upgrading the hosting plan / scaling dynos and increasing workers