简体   繁体   English

Mongoose 异步自定义验证无法按预期工作

[英]Mongoose async custom validation not working as expected

in my schema, I'm performing a lot of asynchronous, custom validations.在我的架构中,我正在执行大量异步的自定义验证。 However, validation is not behaving as I expect it to behave.但是,验证的行为并不像我期望的那样。 Even though promises resolve with "false", mongoose continues validation.即使承诺以“false”解决,猫鼬仍继续验证。 According to their documentation , that shouldn't be the case.根据他们的文档,情况不应该是这样。

Sample schema:示例架构:

    var questSchema = mongoose.Schema({
      questCategory: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        validate: {
          validator: async function (v) {
            await data_verificator.checkIfQuestCategoryExists(v);
          },
          message: (props) => `${props.value} is not a valid quest category id.`,
        },
      },
      fulfillmentPeriod: {
        type: String,
        required: true,
        validate: {
          validator: async function (v) {
            await data_verificator.checkFulfillmentPeriod(this.questCategory, v);
          },
          message: (props) =>
            `${props.value} is an invalid value as it violates the limitations set by the quest category.`,
        },
      },
    })

Note that the custom validation happens asynchronously for those two schema fields.请注意,这两个架构字段的自定义验证是异步发生的。 The validation of the questCategory field works perfectly fine. questCategory字段的验证工作得很好。 If the promise resolves to false , validation fails.如果承诺解析为false ,则验证失败。 However, that's not the case for the fulfillmentPeriod field.但是, fulfillmentPeriod字段并非如此。 Even though the promise resolves to false , the validation succeeds.即使 promise 解析为false ,验证也会成功。

I am not sure why I get this weird behavior.我不确定为什么会出现这种奇怪的行为。 If I were to rewrite validation of the fulfillmentPeriod to look like the following, everything works as expected again.如果我将fulfillmentPeriod验证重写为如下所示,一切都会再次按预期工作。 The promise resolving to false causes the validation to fail.解析为false的承诺会导致验证失败。 Why is that?这是为什么? Why does it work with below code but not with the initial code I pasted above?为什么它适用于下面的代码而不适用于我粘贴在上面的初始代码? Is that because I'm referencing another schema field that is validated asynchronously?那是因为我引用了另一个异步验证的模式字段吗?

validator: async function (v) {
  const result = await data_verificator.checkFulfillmentPeriod(this.questCategory, v);
  return result;
},

Just in case this is important, the checkFulfillmentPeriod function looks like this:以防万一这很重要, checkFulfillmentPeriod函数如下所示:

const checkFulfillmentPeriod = async function (categoryId, period) {
  const connectionManager = require("../configuration").connectionManager;

  var category = await connectionManager.QuestCategoryModel.findOne({
    _id: categoryId,
    availableFulfillmentPeriods: {
      $elemMatch: {
        period: period,
      },
    },
  });

  if (!category) return false;

  return true;
};

The function simply checks if there's a category matching the criteria.该函数只是检查是否有符合条件的类别。 If so, true is returned.如果是,则返回 true。 Otherwise false.否则为假。 From what I've found out, the issue doesn't originate in this function but has something to do with mongoose's validation.从我发现的情况来看,问题并非源于此函数,而是与 mongoose 的验证有关。

The checkIfQuestCategoryExists function looks exactly the same, just with different query settings. checkIfQuestCategoryExists函数看起来完全一样,只是查询设置不同。

I've spent hours on this issue and at this point I just don't see any errors anymore.我已经在这个问题上花费了几个小时,此时我再也看不到任何错误了。

I would appreciate any help/advice I could get!如果我能得到任何帮助/建议,我将不胜感激!

Your validators are missing the return statement thus it is like you were returning a Promise<void> and this doesn't make the validation for mongo to trigger.您的验证器缺少 return 语句,因此就像您返回Promise<void> ,这不会触发 mongo 的验证。 You could either add the return or rewrite your function with a promise being the latter less elegant.您可以添加 return 或重写您的函数,承诺后者不太优雅。

new Promise( (resolve,reject) => {
  .....
  resolve(true/false);
});

Can you try this code:你能试试这个代码吗:

var questSchema = mongoose.Schema({
      questCategory: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        validate: {
          validator: async function (v) {
            return await data_verificator.checkIfQuestCategoryExists(v);
          },
          message: (props) => `${props.value} is not a valid quest category id.`,
        },
      },
      fulfillmentPeriod: {
        type: String,
        required: true,
        validate: {
          validator: async function (v) {
            return await data_verificator.checkFulfillmentPeriod(this.questCategory, v);
          },
          message: (props) =>
            `${props.value} is an invalid value as it violates the limitations set by the quest category.`,
        },
      },
    })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM