Reputation: 803
I am trying to validate mongoose schema, but i could not able to understand one thing which is a validation of type. I am passing number type to a string field and expecting it to fail in validation but it passes. how that is happening, can anyone please explain the logic behind this?
sample.js
const mongoose = require('mongoose');
async function validateSample(sample) {
try {
await sample.validate();
return true;
} catch (error) {
return false;
}
}
async function execMethod(){
var userSchema = new mongoose.Schema({
phone: {
type: String,
minlength: 2,
maxlength: 4,
validate: {
validator: function(v) {
return /^\d+$/.test(v);
},
message: `not a valid phone number!`
},
required: [true, 'User phone number required']
}
});
var User = mongoose.model('user', userSchema);
var validUser = new User({phone: '1234'});
var invalidUser = new User({phone: 1235});
const result = await validateSample(validUser);
const result1 = await validateSample(invalidUser);
console.log(result); // true
console.log(result1) // expected false as number type is assigned to phone. But returns true, why?
}
execMethod()
Upvotes: 2
Views: 1225
Reputation: 106483
That's actually a feature of Mongoose validation.
Before running validators, Mongoose attempts to coerce values to the correct type. This process is called casting the document. If casting fails for a given path, the error.errors object will contain a
CastError
object.Casting runs before validation, and validation does not run if casting fails.
In this case, a number 1235
gets cast to a string '1235'
, which passed the validation just fine.
Now, there's a FR open for providing Mongoose with ability to override cast logic (either disable it completely or customize), but it's Open, not implemented.
Another way is altering casting type-wide (allowed since 5.4), like this:
mongoose.Schema.Types.String.cast(false); // prevents all casts to string
... but it might be cumbersome, as the same rule's applied to all the objects.
Upvotes: 2