重试发送邮件(如果未发送)

时间:2019-07-07 07:46:45

标签: javascript node.js express nodemailer

我正在使用nodemailer通过我的节点应用程序发送电子邮件。有时,直到我尝试两次或三次,电子邮件才起作用,并引发错误。我希望程序一次又一次尝试,直到成功发送邮件为止。

这是我的代码:

const mailOptions = {
    from: from,
    to: client.email,
    subject: 'Your Photos are ready',
    html: mailTemplate
};

transporter.sendMail(mailOptions, function(error, info){
    if (error) {
        res.status(500).json({
              message: "Mail not sent",
              error
        });
    } else {
        res.status(200).json({message: "Mail Sent", response: info.response});
    }
});

如何在if块中使用相同的功能?

4 个答案:

答案 0 :(得分:3)

sendMail包装在返回Promise的函数中

const promiseWrapper = mailOptions => new Promise((resolve, reject) => {
  transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        reject(error);
        return;
    }
    resolve(info);
});

然后在您的路线中将处理程序设为async function,并循环所需的时间,然后检查info是否存在(如果没有发送500则发送200)

app.post('/sendmail', async (req, res) => {
  let info;
  let error;

  for (let i = 0; i < 3; i++) {
    try {
      info = await promiseWrapper(mailOptions);
      break;
    } catch (e) {
      error = e;
    }
  }

  info 
    ? res.status(200).json({ message: "Mail Sent", response: info.response })
    : res.status(500).json({ message: "Mail not send", error }));
});

答案 1 :(得分:0)

你可以先把重试逻辑放在不同的文件中,这样你就可以在不同的地方使用它。 较新版本的 nodemailer 支持 transporter.sendMail

// retry.js
// retries a function, called asynchronously, n amount of times
export async function retry(fn, n) {
  for (let i = 0; i < n; i++) {
    try {
      return await fn()
    } catch (err) {
      console.log(err)
    }
  }
}

并将传输函数传递给重试逻辑,以及您想要重试的次数(在本例中:3)

import {retry} from '../utils/retry'

// ...

app.post('/sendmail', async (req, res) => {
  try {
    retry(
      () =>
        transporter.sendMail({
          // your configuration
          from: from,
          to: client.email,
          subject: 'Your Photos are ready',
          html: mailTemplate
        }),
      3 // max retries
    )
  } catch (err) {
    console.log(err)
    // failed max retry times
    res.sendStatus(500)
  }

  res.sendStatus(200)
})

答案 2 :(得分:-1)

const mailOptions = {
    from: from,
    to: client.email,
    subject: 'Your Photos are ready',
    html: mailTemplate
};

var i;
for(i = 0; i <= 1; i++) {
    transporter.sendMail(mailOptions, function(error, info){
        if (error) {
            res.status(500).json({
                  message: "Mail not sent",
                  error
            });
            i = 0;
        } else {
            i = 2;
            res.status(200).json({message: "Mail Sent", response: info.response});
        }
    });
}

尝试上面的代码,如果发生错误,将一次又一次运行该函数;如果不发生错误,则将退出循环。

答案 3 :(得分:-1)

将其包装到函数中并以这种方式调用:

const mailOptions = {
    from: from,
    to: client.email,
    subject: 'Your Photos are ready',
    html: mailTemplate
};

function sendMail(mailOptions) {
    transporter.sendMail(mailOptions, function(error, info){
        if (error) {
            return sendMail(mailOptions)
        } else {
            return res.status(200).json({message: "Mail Sent", response: info.response});
        }
    });
}

return sendMail(mailOptions);