The following code uses a subschema that produces errors during validate. If that same code is placed in the root document, it fails, but all subschemas does not prevent saving or validating.
The following code should have prevented saving, but succeeded:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const InnerSchema = new Schema(
{
name: {
type: String,
},
},
{ strict: "throw", timestamps: true },
);
InnerSchema.pre('validate', async function () {
console.log('pre-failing')
throw new Error('I have failed you')
console.log('post-failing')
})
const TestSchema = new Schema(
{
subdoc: [ InnerSchema ]
},
{ strict: "throw", timestamps: true },
);
const Test = mongoose.model("Test", TestSchema);
mongoose.connect("mongodb://localhost:27017/test");
const data = {
subdoc: [{name: 'Hey'}]
};
// should throw an error
async function main() {
const res = await Test.create(data);
console.log(res);
}
main()
.then(() => process.exit(0))
.catch((err) => {
console.log(err);
process.exit(1)
});
output:
pre-failing
{ _id: 5bd529a8cc5068b0aaf70cc5,
subdoc:
[ { _id: 5bd529a8cc5068b0aaf70cc6,
name: 'Hey',
createdAt: 2018-10-28T03:14:48.894Z,
updatedAt: 2018-10-28T03:14:48.894Z } ],
createdAt: 2018-10-28T03:14:48.895Z,
updatedAt: 2018-10-28T03:14:48.895Z,
__v: 0 }
Even with the old next
callback it still succeeds:
InnerSchema.pre('validate', function (next) {
console.log('pre-failing')
return next(new Error('I have failed you'))
})
output:
pre-failing
{ _id: 5bd52b133fb801b134f441fd,
subdoc:
[ { _id: 5bd52b133fb801b134f441fe,
name: 'Hey',
createdAt: 2018-10-28T03:20:51.324Z,
updatedAt: 2018-10-28T03:20:51.324Z } ],
createdAt: 2018-10-28T03:20:51.324Z,
updatedAt: 2018-10-28T03:20:51.324Z,
__v: 0 }
Thanks for reporting, will fix asap :+1:
Perfect! thanks
I am seeing this same issue when updating a schema. Possibly a bug?
@bopfer we don't run pre('validate') hooks on query validation currently. We've made some improvements on that front and we'll fix this issue, but for now, as a workaround, define a custom validator on the countryId
path:
const addressSchema = new mongoose.Schema({
address: String,
city: String,
regionId: String,
postalCode: String,
countryId: { type: String, validate: () => { throw new Error('fail'); } }
});