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

Mongoose调用toObject报is not a function错误排查

错误产生原因

核心问题是User.findById(userId)调用时遗漏了await关键字:

  • Mongoose的所有查询方法默认返回Promise对象,只有被await(或者调用.then())解析后,才能拿到实际的Mongoose文档实例
  • Promise原型上不存在toObject()、toJSON()这类Mongoose文档实例的内置方法,直接调用就会抛出xxx is not a function的运行时错误
  • 之前不打印userInfo时代码看似正常,是因为未被await的悬空Promise不会阻断主流程执行,只是会留下未处理Promise的潜在隐患,本质上用户查询的逻辑从一开始就没正确执行。
可行修复方案
  • 给用户查询逻辑补上await,推荐使用Promise.all并行执行文件、用户两个无依赖的查询,减少接口响应耗时
  • 补充查询异常捕获逻辑,和已有文件查询的错误处理对齐
  • 增加用户不存在的空值校验,避免查询无结果时拿到null值调用实例方法再次抛错

修复后的完整业务代码如下:

const { validationResult } = require("express-validator");

const HttpError = require("../models/http-error");
const File = require("../models/file");
const User = require("../models/user");

const getFilesByUserId = async (req, res, next) => {
  const userId = req.params.uid;

  let filePosts;
  let userInfo;
  try {
    // 并行执行两个无依赖的数据库查询,缩短接口等待时间
    [filePosts, userInfo] = await Promise.all([
      File.find({ creator: userId }),
      User.findById(userId)
    ]);
  } catch (err) {
    return next(new HttpError("Fetching failed, please try again.", 500));
  }

  if (!filePosts || filePosts.length === 0) {
    return next(
      new HttpError("Could not find files for the provided user id.", 404)
    );
  }

  // 补充用户不存在的边界校验
  if (!userInfo) {
    return next(new HttpError("Could not find associated user information.", 404));
  }

  console.log(userInfo.toObject({ getters: true }));
  res.json({
    filePosts: filePosts.map((file) => file.toObject({ getters: true })),
  });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:30:53