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

Node.js路由多次调用res.status()报错及ESLint警告解决方案咨询

解决Node.js重置密码路由的重复响应与ESLint警告问题

核心问题是混用async/await与Promise的then/catch语法,导致代码执行顺序不符合预期:

  • 邮件发送的then/catch是异步回调,会在外部的return res.status(200)...执行之后才触发,造成两次响应,触发Cannot set headers after they are sent to the client错误。
  • 移除外部return后,async函数存在潜在的无返回值路径,触发ESLint的expected to return a value at the end of async arrow function警告。

解决方案

将邮件发送的Promise调用改为await风格,统一async/await语法,确保响应只发送一次;同时保证所有代码路径都有明确的返回值,消除ESLint警告。

修改后的完整代码

router.post('/forgot-password', async (req, res) => {
    try {
        // get email from post body
        const { email = '' } = req.body;

        // find user, return if no user
        const thisUser = await User.findOne({ email: email });
        if (!thisUser) {
            await new Promise(r => setTimeout(r, 1000)); // sleep 1 second
            return res.status(200).json({ msg: 'User Does Not Exist' });
        }

        // create reset-password token w/ 1 hour (360,000 milliseconds) expiration, add to user object
        const token = crypto.randomBytes(20).toString('hex');
        const tokenExpires = new Date(Date.now() + 360000);
        const tokenObject = { resetPasswordToken: token, resetPasswordExpires: tokenExpires };
        const userWithToken = await User.findOneAndUpdate({ email: email }, tokenObject);

        // return if error found
        if (!userWithToken) return res.status(404).json({ msg: 'Could not update user with reset-password token' });

        // 改用await处理邮件发送,统一async/await语法
        try {
            await resetPasswordMailer({ email, token });
            console.log(`Success: Reset Password Mailer Emails Both Sent!`);
            return res.status(200).json({ msg: 'Reset password email sent' });
        } catch (err) {
            console.log(`Failure: Reset Password Email Failed...`);
            Sentry.captureException(err);
            return res.status(400).json({ msg: 'Reset password email failed to send' });
        }

        // 移除原有的多余return语句,避免重复响应
    } catch (err) {
        Sentry.captureException(err);
        return res.status(500).json({ statusCode: 500, message: err.message });
    }
});

关键修改点

  • 移除冗余的return语句:删除末尾的return res.status(200).json({ msg: 'Password reset request received' });,避免在邮件发送完成前提前返回响应。
  • 统一异步处理风格:将resetPasswordMailer的then/catch改为await + try/catch,确保代码按顺序执行,邮件发送完成后再返回对应响应,避免重复设置headers。
  • 消除ESLint警告:现在所有代码分支(用户不存在、更新用户失败、邮件发送成功、邮件发送失败、全局catch)都有明确的return res...语句,async函数不存在无返回值的路径,ESLint警告自动消失。

内容的提问来源于stack exchange,提问作者Canovice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:55:31