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

Node.js+MongoDB社交网络Follow/Unfollow接口Postman请求异常排查

问题分析与修复方案

问题代码

module.exports.follow = async (req, res) => {
    if (
      !ObjectID.isValid(req.params.id) ||
      !ObjectID.isValid(req.body.idToFollow)
    )
      return res.status(400).send("ID unknown : " + req.params.id);
  
    try {
      // add to the follower list
      await UserModel.findOneAndUpdate(
        req.params.id,
        { $addToSet: { following: req.body.idToFollow } },
        { new: true, upsert: true }
          .then((data) => res.send(data))
          .catch((err) => res.status(500).send({ message: err }))),

        // add to following list
        await UserModel.findOneAndUpdate(
          req.body.idToFollow,
          { $addToSet: { followers: req.params.id } },
          { new: true, upsert: true }
            .then((data) => res.send(data))
            .catch((err) => res.status(500).send({ message: err })))
    } catch (err) {
      return res.status(500).json({ message: err });
    }
  };
  
  module.exports.unfollow = async (req, res) => {
    if (
      !ObjectID.isValid(req.params.id) ||
      !ObjectID.isValid(req.body.idToUnfollow)
    )
      return res.status(400).send("ID unknown : " + req.params.id);
  
    try {
      await userModel.findOneAndUpdate(
        req.params.id,
        { $pull: { following: req.body.idToUnfollow } },
        { new: true, upsert: true }
          .then((data) => res.send(data))
          .catch((err) => res.status(500).send({ message: err }))),
  
        // Retirer de la liste des followers
        await userModel.findOneAndUpdate(
          req.body.idToUnfollow,
          { $pull: { followers: req.params.id } },
          { new: true, upsert: true }
            .then((data) => res.send(data))
            .catch((err) => res.status(500).send({ message: err })))
    } catch (err) {
      return res.status(500).json({ message: err });
    }
  }

核心问题

  1. 混用async/await与.then/.catch:await已会等待Promise完成,再链式调用.then会导致结构错误,内层.catch会拦截部分错误但外层try/catch无法处理;同时多次调用res.send()会触发"Cannot set headers after they are sent to the client"错误,直接进入外层catch。
  2. 模型名称大小写不一致:follow方法用UserModel,unfollow方法用userModel,Node.js变量大小写敏感,会导致找不到模型报错。
  3. 重复发送响应:一次HTTP请求只能返回一次响应,两次res.send(data)违反协议,必然触发错误。

修复后的代码

const ObjectID = require("mongodb").ObjectID;
// 确保模型路径正确,统一使用大写开头的变量名
const UserModel = require("../models/User");

module.exports.follow = async (req, res) => {
  // 验证两个ID有效性
  if (
    !ObjectID.isValid(req.params.id) ||
    !ObjectID.isValid(req.body.idToFollow)
  ) {
    return res.status(400).send(`ID unknown: ${req.params.id}`);
  }

  try {
    // 并行执行两个更新操作,提升性能
    const [followerUpdate, followingUpdate] = await Promise.all([
      // 更新关注者的following列表
      UserModel.findOneAndUpdate(
        req.params.id,
        { $addToSet: { following: req.body.idToFollow } },
        { new: true, upsert: true }
      ),
      // 更新被关注者的followers列表
      UserModel.findOneAndUpdate(
        req.body.idToFollow,
        { $addToSet: { followers: req.params.id } },
        { new: true, upsert: true }
      )
    ]);

    // 统一返回更新结果
    return res.status(200).json({
      follower: followerUpdate,
      following: followingUpdate
    });
  } catch (err) {
    return res.status(500).json({ message: err.message });
  }
};

module.exports.unfollow = async (req, res) => {
  if (
    !ObjectID.isValid(req.params.id) ||
    !ObjectID.isValid(req.body.idToUnfollow)
  ) {
    return res.status(400).send(`ID unknown: ${req.params.id}`);
  }

  try {
    const [followerUpdate, followingUpdate] = await Promise.all([
      UserModel.findOneAndUpdate(
        req.params.id,
        { $pull: { following: req.body.idToUnfollow } },
        { new: true, upsert: true }
      ),
      UserModel.findOneAndUpdate(
        req.body.idToUnfollow,
        { $pull: { followers: req.params.id } },
        { new: true, upsert: true }
      )
    ]);

    return res.status(200).json({
      follower: followerUpdate,
      following: followingUpdate
    });
  } catch (err) {
    return res.status(500).json({ message: err.message });
  }
};

额外注意事项

  • 确保UserModel的引入路径正确,且模型中已定义following和followers数组字段。
  • 使用Promise.all()并行执行更新,避免串行等待浪费时间。
  • 测试时确认Postman请求参数正确:params.id为当前用户ID,body.idToFollow/body.idToUnfollow为目标用户ID,请求方法为PATCH。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:29:55