【问题标题】:Retry to send mail if not sent如果未发送,请重试发送邮件
【发布时间】:2019-11-17 02:28:03
【问题描述】:

我正在使用 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 块中使用相同的功能?

【问题讨论】:

    标签: javascript node.js express nodemailer


    【解决方案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});
            }
        });
    }
    

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

    【讨论】:

    • For 不会等待异步函数完成。
    • 不知道你用的是异步函数
    【解决方案2】:

    把它包装成一个函数,这样调用:

    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);
    

    【讨论】:

      【解决方案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 是否存在,如果它确实发送200,如果不发送500

      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 }));
      });
      

      【讨论】:

        【解决方案4】:

        你可以先把重试逻辑分开放在不同的文件里,这样你就可以在不同的地方使用了。 较新版本的 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)
        })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-02
          • 2017-08-07
          • 1970-01-01
          • 2011-12-09
          • 2016-05-04
          • 2015-10-09
          • 1970-01-01
          • 2016-08-20
          相关资源
          最近更新 更多