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

NextJS中MongoDB模型在API路由报错,前端调用正常求排查

问题:前端调用Server Action正常,API路由调用时MongoDB模型报错

从前端调用操作MongoDB模型的Server Action完全正常,但通过API路由调用同一个Server Action时出现错误,错误信息如下:

database/question.model.ts (49:0) @
Cannot read properties of undefined (reading 'Question')

报错对应代码行:const Question = models.Question || model("Question", QuestionSchema);

相关代码

1. MongoDB模型代码

import { Schema, models, model, Document } from "mongoose";

export interface IQuestion extends Document {
  quetions: string;
  author: Schema.Types.ObjectId[];
  answers: string;
}

const QuestionSchema = new Schema({
  questions: { type: String, required: true },
  author: { type: Schema.Types.ObjectId, ref: "User" },
  answers: { type: String, required: false },
});

const Question = models.Question || model("Question", QuestionSchema);

export default Question;

2. Server Action代码

export async function getQuestionsCount(params: GetCountByAuthorParams) {
  try {
    connectToDatabase();

    const { author } = params;

    console.log("Author", author);

    const query: FilterQuery<typeof Question> = {
      author,
    };

    const totalQuestions = await Question.countDocuments(query);
    return totalQuestions;
  } catch (error) {
    console.log(error);
    throw error;
  }
}

3. 前端调用(正常工作)

const params = {
  author: userIdRef.current!,
};

const total = await getQuestionsCount(params);
console.log("Total Count", total);

4. API路由调用(无法工作)

const params: GetCountByAuthorParams = {
  author: authorID!,
};

const total = await getQuestionsCount(params);
console.log("Total Count", total);

问题原因与解决方案

核心原因

问题出在数据库连接的时序上:你在Server Action里调用connectToDatabase()时没有用await等待连接完成,就直接去访问Mongoose的models对象了。

前端调用Server Action时,Next.js的执行机制可能隐性处理了连接等待的逻辑;但API路由是独立的请求处理流程,没有这个隐性处理,导致模型加载时models对象还未被Mongoose初始化,所以会报Cannot read properties of undefined (reading 'Question')。

修复步骤

  1. 修改Server Action,等待数据库连接完成
    在connectToDatabase()前添加await,确保连接成功后再操作模型:

    export async function getQuestionsCount(params: GetCountByAuthorParams) {
      try {
        // 关键:添加await等待连接完成
        await connectToDatabase();
    
        const { author } = params;
        console.log("Author", author);
    
        const query: FilterQuery<typeof Question> = { author };
        const totalQuestions = await Question.countDocuments(query);
        return totalQuestions;
      } catch (error) {
        console.log(error);
        throw error;
      }
    }
    
  2. 确保数据库连接函数是单例模式
    检查你的connectToDatabase()实现,要避免重复创建连接,比如可以这样写:

    import mongoose from "mongoose";
    
    let isConnected = false;
    
    export async function connectToDatabase() {
      if (isConnected) {
        return;
      }
    
      try {
        await mongoose.connect(process.env.MONGODB_URI!);
        isConnected = true;
        console.log("数据库连接成功");
      } catch (error) {
        console.error("数据库连接失败:", error);
        throw error;
      }
    }
    
  3. 额外修正:模型接口字段拼写错误
    你的IQuestion接口里的quetions是拼写错误,应该改成questions,和Schema中的字段保持一致,避免后续数据操作出现问题:

    export interface IQuestion extends Document {
      questions: string; // 修正拼写
      author: Schema.Types.ObjectId[];
      answers: string;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:35:29