Next.js 13中使用Mongoose时遭遇的多类错误排查
问题描述
我在Next.js 13的新应用路由中,尝试用Mongoose在路由处理器里创建用户,但遇到了两个连续的错误:
API路由代码
import { NextResponse } from "next/server"; import { User } from "@/mongo"; async function handler(request: Request) { const payload = await request.json(); const user = payload.data.id; if (payload.type === "user.created") { try { console.log(User); const createdUser = await User.create({ userId: user, }); console.log(createdUser); return NextResponse.json({ message: `User: ${user} successfully added` }); } catch (error) { return NextResponse.json({ message: `Error: ${error}` }, { status: 500 }); } } } export const GET = handler; export const POST = handler; export const PUT = handler;
第一个错误:CommentSchema未定义
调用API端点时触发如下错误:
dev: - error Error [TypeError]: Cannot read properties of undefined (reading 'CommentSchema') dev: at Module.CommentSchema (webpack-internal:///(sc_server)/./mongo/index.ts:3:104) dev: at eval (webpack-internal:///(sc_server)/./mongo/Review.ts:38:40) dev: at (sc_server)/./mongo/Review.ts (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:82:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42) dev: at eval (webpack-internal:///(sc_server)/./mongo/index.ts:11:65) dev: at (sc_server)/./mongo/index.ts (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:102:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42) dev: at eval (webpack-internal:///(sc_server)/./app/api/webhooks/user/route.ts:8:64) dev: at (sc_server)/./app/api/webhooks/user/route.ts (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:52:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42) dev: at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fwebhooks%2Fuser%2Froute&page=%2Fapi%2Fwebhooks%2Fuser%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fwebhooks%2Fuser%2Froute.ts&appDir=%2Fhome%2Fethan-krich%2FEthans%20Work%2FeTech%20Stuff%2Fcommerce-karma%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2Fhome%2Fethan-krich%2FEthans%20Work%2FeTech%20Stuff%2Fcommerce-karma&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!:15:145) dev: at (sc_server)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fwebhooks%2Fuser%2Froute&page=%2Fapi%2Fwebhooks%2Fuser%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fwebhooks%2Fuser%2Froute.ts&appDir=%2Fhome%2Fethan-krich%2FEthans%20Work%2FeTech%20Stuff%2Fcommerce-karma%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2Fhome%2Fethan-krich%2FEthans%20Work%2FeTech%20Stuff%2Fcommerce-karma&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D! (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:42:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42) dev: at __webpack_exec__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:682:39) dev: at /home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:683:28) dev: at Object.<anonymous> (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:686:3) dev: at Module._compile (node:internal/modules/cjs/loader:1233:14) dev: at Module._extensions..js (node:internal/modules/cjs/loader:1287:10) dev: at Module.load (node:internal/modules/cjs/loader:1091:32) dev: at Module._load (node:internal/modules/cjs/loader:938:12) dev: at Module.require (node:internal/modules/cjs/loader:1115:19) dev: at require (node:internal/helpers:119:18) dev: at requirePage (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/node_modules/next/dist/server/require.js:112:75) dev: at /home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/node_modules/next/dist/server/load-components.js:80:84) dev: at process.processTicksAndRejections (node:internal/process/task_queues:95:5) dev: at async loadComponentsImpl (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/node_modules/next/dist/server/load-components.js:80:26) dev: at async DevServer.findPageComponentsImpl (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/node_modules/next/dist/server/next-server.js:772:36) { dev: digest: undefined dev: }
相关Schema代码
评论Schema
import mongoose from "mongoose"; export const CommentSchema = new mongoose.Schema ({ text: { type: String, required: true, }, author: { type: mongoose.Types.ObjectId, required: true, ref: "User", }, createdAt: { type: Date, required: true, default: () => Date.now(), }, updatedAt: Date, }) CommentSchema.pre("save", function (next) { this.updatedAt = () => Date.now() as Date; next(); });
用户Schema
import mongoose from "mongoose"; const UserSchema = new mongoose.Schema({ userId: { type: String, required: true, }, bio: String, createdAt: { type: Date, required: true, default: () => Date.now(), }, updatedAt: Date, }); UserSchema.pre ("save", function (next) { this.updatedAt = () => Date.now() as Date next() }) export default mongoose.model("User", UserSchema);
编辑补充:修复CommentSchema后出现新错误
修复CommentSchema的引用问题后,又触发如下错误,且之前的错误偶尔会重现:
dev: - error Error [OverwriteModelError]: Cannot overwrite `User` model once compiled. dev: at Mongoose.model (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/node_modules/mongoose/lib/index.js:563:13) dev: at eval (webpack-internal:///(sc_server)/./mongo/User.ts:25:114) dev: at (sc_server)/./mongo/User.ts (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:92:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42) dev: at eval (webpack-internal:///(sc_server)/./mongo/index.ts:10:63) dev: at (sc_server)/./mongo/index.ts (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:102:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42) dev: at eval (webpack-internal:///(sc_server)/./app/api/webhooks/user/route.ts:8:64) dev: at (sc_server)/./app/api/webhooks/user/route.ts (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/app/api/webhooks/user/route.js:52:1) dev: at __webpack_require__ (/home/ethan-krich/Ethans Work/eTech Stuff/commerce-karma/.next/server/webpack-runtime.js:33:42)
解决方案
1. 修复CommentSchema未定义错误
这个错误根源是Review.ts里引用CommentSchema时路径错误,或者出现了循环引用,按以下步骤排查:
- 核对
Review.ts中导入CommentSchema的路径,确保和文件实际位置一致 - 检查Schema间的依赖:如果
Review用到CommentSchema,同时Comment又依赖Review,会触发循环引用,需要调整结构 - 确认
mongo/index.ts里正确导出了CommentSchema,没有拼写错误
2. 修复User模型重复编译错误
Next.js开发模式的热重载会重复加载模块,而Mongoose不允许同一个模型被多次编译。修改用户Schema文件,先检查模型是否已存在,再创建:
import mongoose from "mongoose"; const UserSchema = new mongoose.Schema({ userId: { type: String, required: true, }, bio: String, createdAt: { type: Date, required: true, default: () => Date.now(), }, updatedAt: Date, }); UserSchema.pre ("save", function (next) { this.updatedAt = new Date(); // 替换原写法,直接生成当前时间更简洁 next() }) // 先检查是否已存在User模型,避免重复创建 export default mongoose.models.User || mongoose.model("User", UserSchema);
同时,建议统一MongoDB连接逻辑,避免每次请求重复连接:
创建mongo/connection.ts:
import mongoose from "mongoose"; async function connect() { // 如果已连接则直接返回 if (mongoose.connections[0].readyState) return; await mongoose.connect(process.env.MONGODB_URI!); } export default connect;
修改API路由,确保每次请求前已连接数据库:
import { NextResponse } from "next/server"; import { User } from "@/mongo"; import connect from "@/mongo/connection"; async function handler(request: Request) { await connect(); const payload = await request.json(); const user = payload.data.id; if (payload.type === "user.created") { try { const createdUser = await User.create({ userId: user, }); return NextResponse.json({ message: `User: ${user} successfully added` }); } catch (error) { return NextResponse.json({ message: `Error: ${error}` }, { status: 500 }); } } // 处理无效请求类型 return NextResponse.json({ message: "Invalid request type" }, { status: 400 }); } // 只保留需要的请求方法,GET/PUT不需要则删除 export const POST = handler;
额外注意事项
- 如果开发模式下仍出现模型重复问题,尝试重启Next.js服务
- 确保所有Schema文件的导入/导出方式统一,避免默认导出和命名导出混淆
- 检查
mongo/index.ts的导出逻辑,示例如下:import User from "./User"; import { CommentSchema } from "./Comment"; export { User, CommentSchema };
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

