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

如何正确使用Mongoose的doValidate方法?遇错求助

问题描述

我有如下Mongoose Schema:

const mySchema = new mongoose.Schema({
   kind: {
      type: String,
      enum: { 
         values: ["dollar", "euro", "pound", "lira"],
         message: "only dollar, euro, pound or lira are allowed"
      },
      required: [true, "kind field is required"]
   }
   // ... 其他字段
})

对应的路由代码:

app.post("/route", async (req, res, next) => {
    // 🏁 在此处编写代码
})

我希望仅验证该Schema中的单个路径(kind字段),而非所有字段。参考GitHub讨论后,我尝试了以下代码:

app.post("/route", async (req, res, next) => {
    // 🏁 
    await mySchema.path("kind").doValidate(req.body.kind)
})

但运行后触发如下错误:

.../node_modules/mongoose/lib/schematype.js:1332
        fn(err);
        ^

TypeError: fn is not a function
    at .../node_modules/mongoose/lib/schematype.js:1332:9
    at processTicksAndRejections (node:internal/process/task_queues:78:11)

请问:

  • 如何正确使用doValidate方法并发挥其作用?
  • 为何该方法无官方文档?
  • 是否可以将其Promise化?

解决方案

1. 正确使用doValidate的方式

doValidate是Mongoose内部方法,它的参数不止要传待验证的值,还必须传入回调函数。正确的回调式用法如下:

app.post("/route", (req, res, next) => {
  mySchema.path("kind").doValidate(req.body.kind, (err) => {
    if (err) {
      return res.status(400).json({ error: err.message });
    }
    // 验证通过后执行后续逻辑
    res.status(200).json({ message: "kind字段验证通过" });
  });
});

如果想用Promise语法,需要手动将其包装为Promise:

app.post("/route", async (req, res, next) => {
  try {
    await new Promise((resolve, reject) => {
      mySchema.path("kind").doValidate(req.body.kind, (err) => {
        err ? reject(err) : resolve();
      });
    });
    res.status(200).json({ message: "kind字段验证通过" });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

不过更推荐使用Mongoose公开的validate方法,它原生支持Promise,无需手动包装:

app.post("/route", async (req, res, next) => {
  try {
    await mySchema.path("kind").validate(req.body.kind);
    res.status(200).json({ message: "kind字段验证通过" });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

2. 为何doValidate无官方文档?

doValidate是Mongoose的内部私有方法,仅用于框架内部逻辑调用,并非为开发者设计的公开API。这类方法的参数、行为可能随Mongoose版本迭代发生变更,官方不将其纳入文档,是为了避免开发者依赖后在版本升级时出现兼容性问题。

3. 是否可以将其Promise化?

可以,但需要手动用Promise包装(如上述示例)。不过更建议使用公开的validate方法,它本身支持Promise,稳定性和兼容性更有保障。


内容的提问来源于stack exchange,提问作者Islam Y-

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:09:23