Search code examples
javascriptrecursionnodemailer

Retry mechanism to send an email from different host


I'm sending an email using nodemailer and in case a send is faild, I wanna use a different host in a retry.

I tried:

let tries = 0;
let maxTries = 2;
  const sendEmail = async () => {
    tries += 1;
    
    if (tries === maxTries) return;

    const transporter = nodemailer.createTransport({
        host: tries === 1 ? host1 : host2,
        port: port,
        secure: false
    });

    // mailOptions object here....

    await transporter.sendMail(mailOptions, (err, info) => {
        if (err) {
            return sendEmail();
          } else {
            console.log('Email Sent Successfuly');
        }
    });
}

It works but it feels a bit cumbersome.

Is there a better way to implement this feature?


Solution

  • How about something like this (updated per suggestions from Bergi)?

    const sendEmail = async (mailOptions, hosts = [host1, host2]) => {
      if (hosts .length == 0) {
        return Promise .reject ('all hosts failed')
      }
      // configure transporter  
      try { 
        const info = await transporter .sendMail (mailOptions); 
        return 'Email sent successfully'; 
      } catch (err) { 
        return sendEmail (option, hosts .slice (1)) 
      }
    }
    

    (Please don't use this original verion, for the reason's Bergi pointed out)

    // DO NOT USE
    const sendEmail = async (options, hosts = [host1, host2]) => {
      if (hosts .length == 0) {
        return Promise .reject ('all hosts failed')
      }
      // configure transporter
      return new Promise ((resolve, reject) => {
        transporter .sendMail (mailOptions, (err, info) => {
          if (err) {
            return sendEmail (option, hosts .slice (1))
          } else {
            resolve ('Email Sent Successfuly');
          }
        })
      })
    }

    It could easily be extended to handle something like:

    const hosts = [{host: host1, tries: 3}, {host: host2, tries: 1}, {host: host3, tries: 5}]
    sendMail (options, hosts)
    

    so that it would try the first host three times, then a second one once, then a third one five times before giving up.