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

Mongoose出现OverwriteModelError,无法定位代码问题

解决MERN栈待办应用的OverwriteModelError问题

错误原因

  1. 你在/todo-submit和/fetch_records两个路由中,每次请求都会重新定义Schema并创建名为todo的Mongoose模型。Mongoose不允许重复注册同名模型,这直接触发了OverwriteModelError。
  2. fetch_records路由的finally块里调用mongoose.connection.close()会关闭数据库连接,导致后续所有请求都无法访问数据库。

修复方案

1. 全局定义Mongoose模型,避免重复创建

把Schema和Model的定义移出路由逻辑,放在文件顶部(数据库连接完成后),确保整个应用生命周期内只创建一次模型。

修改后的完整代码:

const express = require('express')
const config = require('config')
const app = express()
const port = config.get("PORT")
const cors = require('cors')
const bodyParser = require('body-parser')

const mng = require('./db/mongoose')
const mongoose = require('mongoose')

// 全局定义Schema与Model,仅执行一次
const todoSchema = new mongoose.Schema({
  task: String,
  dueDate: Date,
  isAccomplished: Boolean
}, {versionKey: false});

// 第三个参数指定集合名,避免Mongoose自动将模型名转为复数
const Todo = mongoose.model("todo", todoSchema, "todo")

// 中间件配置
app.use(express.json())
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))

// 提交待办事项路由
app.post('/todo-submit', async (req, res) => {
  let message = {}
  const item = {
    task: req.body.task,
    dueDate: req.body.dueDate,
    isAccomplished: false
  };

  try {
    await Todo.create(item)
    message = {'success': true, 'message': 'Records have been successfully inserted'}
  } catch (error) {
    message = {'success': false, 'errorMessage': error.message}
  }

  res.json(message)
})

// 获取待办事项路由
app.get('/fetch_records', async (req,res) => {
  try {
    // 用select过滤返回字段,无需重新定义Schema
    const records = await Todo.find({}).select('task dueDate')
    res.json(records);
  } catch (error) {
    console.error(error)
    res.status(500).json({message: 'There was an error while fetching records'})
  }
  // 移除手动关闭连接的代码,Mongoose会自动维护连接池
});

app.listen(port, () => {
  console.log("This server has been started on port " + port + "!")
})

2. 关键修改点说明

  • 全局模型注册:将Schema和Model的创建逻辑放在路由之外,彻底避免重复注册模型的问题。
  • 移除连接关闭操作:Mongoose默认维护数据库连接池,手动关闭连接会导致后续请求无法访问数据库。
  • 字段过滤优化:使用select('task dueDate')过滤返回字段,比重新定义Schema更简洁高效。
  • 错误信息安全:返回error.message而非完整error对象,避免暴露服务器内部敏感信息。

内容的提问来源于stack exchange,提问作者m.kreyn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:57:45