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
相关产品推荐
相关产品推荐

