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

使用Mongoose校验发POST请求额外出现Cannot read property 'get'报错

问题原因排查

1. 直接触发TypeError的核心原因

GET请求的catch块中错误地仅传递了字符串类型的错误信息:next(error.message),而非完整的Error对象。Express的错误处理机制要求next()传递完整Error对象,且错误处理中间件必须定义为(err, req, res, next)四参数格式,传递非Error对象会导致后续错误处理时上下文丢失,最终调用res.json()时触发Cannot read property 'get' of undefined异常。

2. Schema配置顺序错误

你先调用mongoose.model("Person", personSchema)生成了Person模型,之后才设置personSchema.set("toJSON", {...})序列化规则,该规则不会生效到已生成的模型上,调用.toJSON()时会出现预期外的行为。同时代码中重复生成了两次Person模型,也会导致配置异常。

3. POST请求字段类型不匹配

Schema中number字段定义为String类型,但POST路由中使用Number(body.number)将其转为数字类型,虽然Mongoose会做隐式转换,但不符合字段定义规范,也会增加校验逻辑的不可控性。

修复方案
  1. 修正Schema配置顺序,删除重复模型生成
// 先配置Schema规则和序列化逻辑
personSchema.plugin(mongooseUniqueValidator);
mongooseUniqueValidator.defaults.message = "Error, expected {PATH} to be unique.";

personSchema.set("toJSON", {
  transform: (document, returnedObj) => {
    returnedObj.id = returnedObj._id.toString();
    delete returnedObj._id;
    delete returnedObj.__v;
  },
});

// 最后生成模型,只生成一次
const Person = mongoose.model("Person", personSchema);
module.exports = Person;
  1. 修正POST请求字段赋值
app.post("/api/persons", (request, response, next) => {
  const body = request.body;
  const person = new Person({
    name: body.name,
    // 不要转Number,直接传入字符串类型值匹配Schema定义
    number: body.number,
    date: new Date(),
  });
  person
    .save()
    .then((savedPerson) => response.json(savedPerson.toJSON()))
    .catch((error) => next(error));
});
  1. 修正GET请求catch逻辑
app.get("/api/persons", (req, res, next) => {
  Person.find({})
    .then((persons) => res.json(persons.map((person) => person.toJSON())))
    // 传递完整Error对象,不要仅传错误信息字符串
    .catch((error) => next(error));
});
  1. 确保错误处理中间件符合Express规范
// 必须按 err → req → res → next 的顺序定义四个参数,才会被识别为错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.message);
  if (err.name === "ValidationError") {
    return res.status(400).json({ error: err.message });
  }
  // 其他错误类型处理逻辑
  res.status(500).json({ error: "服务器内部错误" });
});
// 错误处理中间件必须挂载在所有路由之后

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:39:04