Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING CHANGE: remove _executionStack, make validate() async function and call Kareem hooks directly vs through wrappers #15298

Open
wants to merge 3 commits into
base: 9.0
Choose a base branch
from

Conversation

vkarpov15
Copy link
Collaborator

Summary

Partially a fix for #14906, but also includes some related followup work because, in addition to removing _executionStack, we should do the same for parallel validation error. However, I took the time to refactor validate() to be an async function, to take advantage of async stack traces. With this PR, you get async stack traces when calling document.validate():

Error.stackTraceLimit = 20;

const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/mongoose_test");


const userSchema = new mongoose.Schema({
  name: { type: String, required: true, validate: v => v.length > 3 },
  age: Number,
});
userSchema.pre('validate', function() {
  if (this.name === 'secret') {
    throw new Error('name cannot be secret');
  }
});

const User = mongoose.model("User", userSchema);

async function runDemo() {
  const doc = new User({ name: 'A' });
  await doc.validate();

  //doc.name = 'secret';
  //await doc.validate();
  // await doc.save();
}

runDemo().catch(err => console.log(err.stack));

Output:

$ node gh-14250.js 
ValidationError: User validation failed: name: Validator failed for path `name` with value `A`
    at Document.invalidate (/mongoose/lib/document.js:3335:32)
    at doValidateCallback (/mongoose/lib/document.js:3105:17)
    at validate (/mongoose/lib/schemaType.js:1403:7)
    at SchemaType.doValidate (/mongoose/lib/schemaType.js:1387:7)
    at /mongoose/lib/document.js:3097:18
    at new Promise (<anonymous>)
    at validatePath (/mongoose/lib/document.js:3096:11)
    at model.$__validate (/mongoose/lib/document.js:3043:21)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async model.validate (/mongoose/lib/document.js:2653:5)
    at async runDemo (/gh-14250.js:22:3)

Without this PR, stack trace is not helpful:

$ node gh-14250.js 
ValidationError: User validation failed: name: Validator failed for path `name` with value `A`
    at Document.invalidate (/mongoose/lib/document.js:3329:32)
    at /mongoose/lib/document.js:3090:17
    at /mongoose/lib/schemaType.js:1407:9
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11)

Examples

@vkarpov15 vkarpov15 added this to the 9.0 milestone Mar 4, 2025
Copy link
Collaborator

@hasezoey hasezoey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

callback(null, _this);
});
const error = _complete();
await this._execDocumentPostHooks('validate', error);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to confirm, this should not still be validate:error?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants