Nodemailer无响应且Postman返回500错误排查求助
忘记密码控制器邮件发送问题排查
我正在开发一个“忘记密码”控制器,用于向用户邮箱发送验证token,通过Nodemailer编写了邮件发送函数并在forgotPassword控制器中调用。目前函数看似未正常工作,Postman测试返回500错误,但控制台无任何错误输出,即使catch块里加了console.log,希望排查问题。
忘记密码控制器代码
const jwt = require('jsonwebtoken'); const db = require('../../models/index'); const sendEmail = require('../../utils/mailer'); exports.store = async (req, res) => { const { email } = req.body; const secret = process.env.JWT_SECRET; try { const user = await db.User.findOne({ where: { email } }); if (!user) { res.status(400).json('User does not exist.'); } const token = jwt.sign({ id: user.id }, secret, { expiresIn: process.env.EXPIRES_FORGOTPASS, }); await user.update({ tokenReset: token, }); sendEmail({ from: 'noreply@email.com', to: 'admin@gmail.com', subject: 'Reset your password', text: `Token sending email to reset password account from ${user.email}`, html: `<h2>Token sending email to reset password account from ${user.email}</h2> <h4>${token}</h4> `, }); return res.status(200).json('Check the verification link in your email!'); } catch (err) { return console.log(err); } }
Nodemailer邮件发送函数代码
const nodemailer = require('nodemailer'); const port = process.env.EMAIL_PORT; const sendEmail = async ( from, to, subject, text, html ) => { try { const transport = nodemailer.createTransport({ host: process.env.EMAIL_HOST, port: port, auth: { user: process.env.EMAIL_AUTH_USER, pass: process.env.EMAIL_AUTH_PASS, } }); await transport.sendMail({ from: from, to: to, subject: subject, text: text, html: html, }); console.log('Email send succesfully'); } catch (err) { console.log(err); } } module.exports = sendEmail;
问题根源与修复方案
1. 用户不存在时未终止流程
当查询不到用户时,代码返回了400响应但未加return,后续代码会继续执行。此时user为undefined,访问user.id会抛出错误进入catch块,但catch块仅打印错误,未向客户端返回响应,导致Postman收到500错误。
修复:在用户不存在的判断分支添加return,终止后续代码执行:
if (!user) { return res.status(400).json('User does not exist.'); }
2. sendEmail函数参数不匹配
控制器调用sendEmail时传入的是一个对象,但函数定义为接收5个独立参数,导致函数内部所有参数值为undefined,触发邮件发送错误。同时sendEmail是异步函数,控制器调用时未加await,且函数内部捕获错误后未重新抛出,上层try/catch无法感知该错误。
修复方案二选一:
- 方案一:按函数定义传递独立参数并添加
await
await sendEmail( 'noreply@email.com', 'admin@gmail.com', 'Reset your password', `Token sending email to reset password account from ${user.email}`, `<h2>Token sending email to reset password account from ${user.email}</h2> <h4>${token}</h4>` );
- 方案二:修改sendEmail函数接收对象参数(更易维护)
const sendEmail = async ({ from, to, subject, text, html }) => { try { const transport = nodemailer.createTransport({ host: process.env.EMAIL_HOST, port: port, auth: { user: process.env.EMAIL_AUTH_USER, pass: process.env.EMAIL_AUTH_PASS, } }); await transport.sendMail({ from, to, subject, text, html }); console.log('Email sent successfully'); } catch (err) { console.log(err); throw err; // 重新抛出错误,让上层捕获 } }
3. catch块未处理客户端响应
控制器的catch块仅打印错误,未向客户端返回错误状态码和信息,导致请求无响应或返回500。
修复:在catch块中添加错误响应:
catch (err) { console.log(err); return res.status(500).json('An error occurred while processing your request.'); }
内容的提问来源于stack exchange,提问作者Routfin
相关产品推荐
相关产品推荐

