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

MongoClient循环引用JSON转换错误:ID获取用户接口失败

问题分析与解决方案

核心问题

你遇到的TypeError: Converting circular structure to JSON错误,根源有两个:

  1. Mongoose的findById/findOne是异步方法,返回的是Promise对象而非实际用户文档。直接把Promise传给res.json()时,Promise内部包含MongoClient的循环引用结构,JSON序列化就会报错。
  2. userService存在导出函数名不匹配问题:定义的是findUserById,但导出的是findUserByProperty,这会导致controller调用的函数实际不存在(当前循环引用错误优先触发,但这个问题必须修正)。

另外还有两个细节问题:

  • controller里抛出错误的写法错误,error('User not found', 404)不是正确的错误构造方式。
  • 未处理Mongoose查询可能抛出的数据库异常。

修正步骤

1. 修正userService代码

将查询改为异步,同时修正导出函数名:

const User = require('../models/User');

// 改为异步函数,用await获取实际文档
const findUserById = async (key, value) => {
    if (key === '_id') {
        return await User.findById(value);
    }
    return await User.findOne({ [key]: value });
};

// 导出正确的函数名
module.exports = {
    findUserById
};

2. 修正controller代码

用await处理异步查询,同时修正错误抛出逻辑:

// 标记函数为async
const getUserById = async (req, res, next) => {
    const userId = req.params.userId;

    try {
        // 用await获取实际用户文档
        const user = await userService.findUserById('_id', userId);
        if (!user) {
            // 构造标准错误对象,自定义status便于后续处理
            const err = new Error('User not found');
            err.status = 404;
            throw err;
        }

        return res.status(200).json(user);
    } catch (e) {
        // 把错误传递给express全局错误处理中间件
        next(e);
    }
};

3. 补充(可选):添加全局错误处理中间件

在server.js中添加统一错误处理逻辑,避免异常暴露敏感信息:

app.use((err, req, res, next) => {
    const statusCode = err.status || 500;
    res.status(statusCode).json({
        message: err.message || 'Internal Server Error'
    });
});

验证

修改后重启服务,用Thunder Client测试:

  • 传入存在的用户ID,会正常返回用户JSON数据。
  • 传入不存在的ID,会返回404状态码和"User not found"提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:00:56