如何正确使用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-
相关产品推荐
相关产品推荐

