You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:10:44