Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't error handling work in nodemailer?

I am trying to set up a really simple contact form with nodemailer and it works fine, but my issue is that it doesn't handle errors. The page should redirect if an error is thrown, but instead the redirect does not happen and the app stops running. I cannot for the life of me figure out why this is happening. Here is my code:

if (req.method === 'POST') {
  const name = req.body.name;
  const email = req.body.email;
  const msg = req.body.message;

  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      user: 'myemail', // left out here
      pass: process.env['GMAIL_PASS']
    }
  });

  const mailOptions = {
    from: 'myemail', // left out here
    to: 'myemail', // left out here
    subject: 'Portfolio Inquiry',
    text: `
          Name: ${name}
          Email: ${email}
          Message:${msg}`
  };

  transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      // If an error is thrown, it should redirect back to the page with a fail message
      return res.redirect('/about?send=fail#contact');
    } else {
      return res.redirect('/about?send=success#contact');
    }
  });
}

If I introduce an error into the script by commenting out something important or just throwing an error, as I said the error handling block in the sendMail callback doesn't do anything. As I said, it does properly work and send the email, but if something went wrong I definitely want my user to know about it. Could anyone help me understand how to correct this issue?

like image 520
Michael Alexander Avatar asked May 02 '20 15:05

Michael Alexander


People also ask

How do I debug Nodemailer?

Debugging options in Nodemailer It is simple with Nodemailer: set both debug and logger to true and you will be able to see all the data which is passed to the server as an output in console. This way, you will be able to analyze email sending process and quickly fix errors, if there are any.

What is SMTP in Nodemailer?

SMTP is the main transport in Nodemailer for delivering messages. SMTP is also the protocol used between different email hosts, so its truly universal. Almost every email delivery provider supports SMTP based sending, even if they mainly push their API based sending.

Is Nodemailer paid?

Nodemailer can be purchased from Kreata OÜ. License fee (excluding VAT) for a 1 year license is $820.


2 Answers

I finally figured out a solution to this myself. Here is a wrapper function:

function sendEmail(req) {
    const name = req.body.name;
    const email = req.body.email;
    const msg = req.body.message;

    const transporter = nodemailer.createTransport({
        host: 'smtp.gmail.com',
        port: 587,
        secure: false,
        service: 'gmail',
        auth: {
            user: //left out,
            pass: process.env['GMAIL_PASS']
        }
    });

    const mailOptions = {
        from: //left out
        to: //left out
        subject: 'Portfolio Inquiry',
        text: `
Name: ${name}
Email: ${email}
Message:

${msg}`};

    return transporter.sendMail(mailOptions);
}

Then the function call:

try {
   await sendEmail(req);
   return res.redirect('/about?send=success#contact')
} catch (err) {
   return res.redirect('/about?send=fail#contact')
}

Because the sendMail function returns a promise when no callback is given, you can call it in a try...catch block.

like image 135
Michael Alexander Avatar answered Oct 23 '22 15:10

Michael Alexander


As stated already:

Because the sendMail function returns a promise when no callback is given, you can call it in a try...catch block.

sendMail returns a promise, you can chain .then() and .catch()for handling like:

// async/await is not available in the global scope, so we wrap in an IIFE
(() => {
    const result = await transporter
        .sendMail(mailOptions)
        .then(console.log)
        .catch(console.error);

    // do something with `result` if needed
})();
like image 21
lacy Avatar answered Oct 23 '22 16:10

lacy