Mongoose:MongoError 不会阻止 运行 的预挂钩?

Mongoose: MongoError won't prevent pre hooks to run?

我正在使用 Mocha 在我的 API 中进行一些测试,我注意到当我有一个带有 unique: true 的字段并在重复的字段上进行测试时,我的所有 pre('save') 仍然被调用。我做错了什么吗?

user.js

const UserSchema = new Schema({
  email: {
    type: String,
    unique: true
  }
});

UserSchema.pre('save', function test(next) {
  console.log(123);
});

test.js

var user1 = await User.findOne({ email: "test@test.com" });
var user2 = new User({ email: "test@test.com" });
await user2.save()

控制台:

123
MongoError: E11000 duplicate key error collection (...)

Here有我测试的图片。在“有效时创建新文档”中,我创建了两个新用户。在“电子邮件是唯一的...”测试中,我尝试使用与之前创建的相同的电子邮件创建另一个。 “1234567”是 console.log 我放在我的 pre hook 里面。

经过大量研究,我发现了 unique 和 pre hooks 是如何工作的。

This 是解决此类问题的最佳方法。

编辑:此答案的一些细节,因为 Tyler 指定它可能会变得无效。

就我而言,我的预存具有重要的关系逻辑。因此,当我尝试保存无效文档时,它的所有关系都与错误的文档相关联。

由于异步预挂钩是一起调用的,我必须保证我的唯一验证在所有事情之前被调用。使用 .path('field').validate 是迄今为止我发现的最好的方法,因为它甚至在 .pre('validate') 之前被调用。这是我的代码:

UserSchema.path('email').validate(async function validateDuplicatedEmail(value) {
    if (!this.isNew && !this.isModified('email')) return true;

    try {
        const User = mongoose.model("User");

        const count = await User.countDocuments({ email: value });
        if (count > 0) return false;

        return true;
    }
    catch (error) {
        return false;
    }
}, "Email already exists");