1

I am working on versioning changes for an application. I am making use of the mongoose pre-hook to alter the queries before processing according to the versioning requirements, I came across a situation where I need to do a separate query to check whether the other document exists and if it is I don't have to execute the current query as shown below,

schema.pre('find', { document: false, query: true }, async function (next) {
  const query = this.getQuery();
  const doc = await model.find(query).exec();
  if (!doc) {
    const liveVersion = { ...query, version: "default" };
    this.setQuery(liveVersion);
  } else {
    return doc;
  }
});

In the above find pre-hook, I am trying to

  • check the required doc exists in the DB using the find query and return if does exist and
  • if the document does not exist, I am executing the query by setting the default version based query.

The problem here is mongoose will execute the set query no matter what and the result its returning is also the one which I got for the this.setQuery, not the other DB query result(doc).

Is there a way to stop the default query execution in mongoose pre-hook?

Any help will be appreciated.

kgangadhar
  • 4,886
  • 5
  • 36
  • 54

1 Answers1

0

The only way to stop the execution of the subsequent action would be to throw an error, so you can throw a specific error in else, with your data in the property of the error object, something like:

else {
  let err = new Error();
  err.message = "not_an_error";
  err.data = doc;
}

but that would mean wrapping all your find calls with a try/catch, and in the catch deal with this specific error in the way of extracting your data, or throw for the main error checking if it's an actual error. In the end you'll be having a very ugly code and logic.

This is specifically for the way you ask it, but normally you can just define another method, like findWithCheck(), and do your checks of the pre hook above in this custom method.

Of course you could try also overriding the actual find(), but that would be overkill, and in this case it means pretty much breaking the whole thing more for test purposes rather than development.

Ncifra
  • 663
  • 6
  • 15