【问题标题】:Nodemailer: Cannot read property 'then' of undefinedNodemailer:无法读取未定义的属性“then”
【发布时间】:2019-08-27 17:03:32
【问题描述】:

我正在设置 nodemailer 以发送电子邮件。所有电子邮件都已正确发送,但有一个我无法解决的错误。错误信息是: TypeError: 无法读取未定义的属性 'then'

这是我的代码:

 transporter.sendMail(mailOptions, (error, info) => {
   console.log(mailOptions);
  })
  .then((ok) => {
    return ok;
  })
  .catch((error) => {
    if (error.name = "SequelizeValidationError") {
      let response = Errors.errorResponse(error);
      res.status(422).send(response);
    } else {
      let response = Errors.errorResponse(error);
      res.status(500).send(response);
    }
  });

【问题讨论】:

  • callbacks()then() 一起使用是不对的。使用其中一个(then() 仅当返回值是一个成熟的承诺时)。

标签: node.js


【解决方案1】:

您将回调传递给transporter.sendMail(),因此它不会返回承诺。这就是为什么你不能使用.then()

来自他们的文档:

如果未设置回调参数,则该方法返回一个 Promise 对象。 Nodemailer 本身并没有在内部使用 Promises,但为了方便起见,它会将返回值包装到 Promise 中。

你应该做什么:

transporter.sendMail(mailOptions)
  .then((ok) => {
    return ok;
  })
  .catch((error) => {
    if (error.name = "SequelizeValidationError") {
      let response = Errors.errorResponse(error);
      res.status(422).send(response);
    } else {
      let response = Errors.errorResponse(error);
      res.status(500).send(response);
    }
  });

【讨论】:

  • 非常感谢。现在它工作正常,但 Nodemailer 发送了两次电子邮件。这怎么可能?
  • 能否将mailOptions 的内容添加到您的问题中?你确定你没有调用 sendMail 两次吗?
【解决方案2】:

尝试在尝试使用时添加异步关键字,那么它应该是使用承诺应该使用的键

async function sendASNICMAIL() {

 transporter.sendMail(mailOptions, (error, info) => {
    console.log(mailOptions);
}).then((ok) => {
    return ok;
}).catch((error) => {
    if (error.name = "SequelizeValidationError") {
        let response = Errors.errorResponse(error);
        res
            .status(422)
            .send(response);
    } else {
        let response = Errors.errorResponse(error);
        res
            .status(500)
            .send(response);
    }
});

} 试试这个并告诉我是否工作或不提交 ]

【讨论】:

  • 是的,异步关键字工作正常。非常感谢您的回答!!
  • 如果他不使用 await,async 关键字有什么帮助?
  • 有写异步函数的方法,但是await可能已经写入或使用了key然后catch async function f() { return 1; } f().then(alert); // 1
【解决方案3】:

您通过提供回调告诉 nodemailer 您不想要 Promise。你可以

  1. 移除回调并使用promise:

    transporter.sendMail(mailOptions)
    .then((ok) => {
      console.log(mailOptions);
      return ok;
    })
    .catch((error) => {
      console.log(mailOptions);
      if (error.name = "SequelizeValidationError") {
        let response = Errors.errorResponse(error);
        res.status(422).send(response);
      } else {
        let response = Errors.errorResponse(error);
        res.status(500).send(response);
      }
    });
    

  2. 改用回调:

    transporter.sendMail(mailOptions, (error, ok) => {
        console.log(mailOptions);
        if (error) {
          if (error.name = "SequelizeValidationError") {
            let response = Errors.errorResponse(error);
            res.status(422).send(response);
          } else {
            let response = Errors.errorResponse(error);
            res.status(500).send(response);
          }
        }
        else {
          // Do whatever you want with "ok"
        }
    });
    

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 2017-04-21
    • 2019-08-19
    • 1970-01-01
    • 2016-10-23
    • 2014-09-07
    • 2015-09-08
    • 2018-01-12
    相关资源
    最近更新 更多