Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
256 views
in Technique[技术] by (71.8m points)

javascript - 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. 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. If the promise resolves to false, validation fails. However, that's not the case for the fulfillmentPeriod field. Even though the promise resolves to false, the validation succeeds.

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. The promise resolving to false causes the validation to fail. 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:

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. 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.

The checkIfQuestCategoryExistsfunction looks exactly the same, just with different query settings.

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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. You could either add the return or rewrite your function with a promise being the latter less elegant.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...