【问题标题】:Mongoose saves invalid data without throwing validation errors if model.validate() is called first如果先调用 model.validate(),Mongoose 会保存无效数据而不会引发验证错误
【发布时间】:2020-01-06 03:26:44
【问题描述】:

MongoDB 4.2.2 和 Mongoose 5.8.3(最新)和 NodeJS 13.3.0 (Windows x64)

如果我创建模式和模型,然后创建模型的实例并添加一些数据,然后运行validate(),然后save():即使validate() 失败,数据也会保存到集合中,没有引发额外的验证错误。

这是一个错误,还是我做错了什么?

这是测试代码:

var mongoose = require('mongoose')
mongoose.connect("mongodb://user:pass@localhost/mydb")
db = mongoose.connection

var Schema = mongoose.Schema


var PartSchema = new Schema({
    name: {
        type: String,
        required: true,
        validate: {
            validator: (v) => v !== 'asdf'  // Don't allow name to be 'asdf'
        }
    },
    number: {
        type: String,
        required: true,
        validate: {
            validator: (v) => !v.includes(' ')  // Don't allow spaces in part number.
        }
    }
})

var ProductSchema = new Schema({
    name: String,
    parts: [PartSchema]
})

var Part = mongoose.model('Part', PartSchema)
var Product = mongoose.model('Product', ProductSchema)

var p1 = new Product({name:"Baseball Bat", parts:[ new Part({name:"First part", number: "003344"}), new Part({name: "Second part", number: "554422"}) ]})

p1.parts.push(new Part({name: "No number, so invalid"}))  // this one is invalid because no part number is specified (required)
p1.parts.push(new Part({name: 'asdf', number: 'zzzzzaaaa'}))  
p1.parts.push(new Part({name: 'bbbb', number: 'with a space'})) // This one is invalid because number has spaces.
p1.validate()
    .then(() => {console.log('Validation successful')})
    .catch((err) => { console.log("Validation failed.")})
p1.save()
    .then(()=>{ console.log("Saved successfully")})
    .catch((err)=>{console.log("Save ERROR", err)})

运行此代码会产生以下结果:

Validation failed.
Saved successfully

并且新文档出现在数据库中:

但是,如果我在调用save() 之前删除了p1.validate(),则会触发保存函数的catch() 块并且不会保存该项目:

Save ERROR Error [ValidationError]: Product validation failed: parts.2.number: Path `number` is required., parts.3.name: Validator failed for path `name` with value `asdf`, parts.4.number: Validator failed for path `number` with value `with a space`
    at ValidationError.inspect 
... snipped

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    您可能需要在承诺链中使用p1.save()

    p1.validate()
      .then(res => {
        console.log("Validation successful");
      })
      .then(() => {
        return p1.save();
      })
      .then(res => {
        console.log("saved success ", res);
      })
      .catch(err => {
        console.log("Some error.", err);
      });
    

    【讨论】:

    • 我可以这样做,但关键是这似乎是一个错误:如果我调用 validate,它不应该干扰 save 也进行自己的验证,无论它们是否被调用在同一个承诺链中。我可能想致电validate,然后根据这些值是否有效执行其他操作。 save 应该始终重新验证,无论我是否刚刚验证。
    • @RyanGriggs 是的,我同意,这是 mongoose 库中的一个错误。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    相关资源
    最近更新 更多