nodemailer报错UnhandledPromiseRejectionWarning及No recipients defined如何解决
错误原因分析
1. Cannot set headers after they are sent to the client 报错原因
你在两个位置操作了HTTP响应返回:
mailer.contact方法内部已经调用了res.json()/res.status()向客户端返回了响应- 回到
create控制器后,你又执行了return res.send("Dummy :product created")
HTTP协议规定同一个请求只能返回一次响应,重复操作就会触发该错误。
2. No recipients defined 报错原因
你调用transporter.sendMail时参数使用错误:
- 你把
mailoptions额外套了一层对象,导致nodemailer读取不到收件人to字段 - 同时混用了
await和回调函数两种调用方式,逻辑执行混乱 - 另外
contact方法catch块中引用的message变量未定义,也会触发额外报错
修复后的代码
建议将发邮件逻辑和HTTP响应逻辑解耦,不要在邮件工具方法里操作响应对象:
1. 修正nodemailer控制器代码
const nodemailer = require("nodemailer"); // 仅保留发邮件核心逻辑,不操作HTTP响应对象 exports.contact = async () => { try { let transporter = nodemailer.createTransport({ service: "gmail", host: "smtp.gmail.com", port: 587, secure: false, // 465端口填true,其余端口填false auth: { user: "**********@gmail.com", pass: "password", // 谷歌邮箱需替换为两步验证后的应用专用密码,不可直接用账号原密码 }, }); const mailoptions = { from: "**********@gmail.com", to:"**********@gmail.com", subject: "Sending Email using Node.js", text: "That was easy!", }; // 直接传入mailoptions参数,不套额外对象,使用await接收结果 await transporter.sendMail(mailoptions); return { success: true } } catch (error) { console.log("发邮件失败:", error); return { success: false, msg: error.message } } };
2. 修正产品创建控制器代码
const mailer = require("../config/nodemailer"); const Product = require("../models/Product"); // 补全Product模型引入,你原代码遗漏了该部分 module.exports.create = async (req, res) => { try { const product = new Product({ name: req.body.name, description: req.body.description, isFeatured: req.body.isFeatured, }); await product.save(); // 写入产品数据到数据库 const mailRes = await mailer.contact(); // 调用发邮件方法 if (!mailRes.success) { // 可根据业务需求调整:发邮件失败时可直接报错,也可返回产品创建成功仅提示邮件发送失败 return res.status(500).json({ message: `产品创建成功,但邮件发送失败:${mailRes.msg}` }); } res.status(200).json({ product, msg: "产品创建成功,邮件已发送" }); } catch (error) { console.log("******插入数据出错******", error); res.status(500).json({ message: error.message }); } };
内容的提问来源于stack exchange,提问作者amit perane
相关产品推荐
相关产品推荐

