Skip to content

Commit 444d941

Browse files
authored
Merge pull request #15580 from piotracalski/piotracalski-gh15579
Bugfix: `Model.validate()` hangs when all paths fail casting
2 parents adc1799 + 66c6dd3 commit 444d941

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

lib/model.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4304,6 +4304,10 @@ Model.validate = async function validate(obj, pathsOrOptions, context) {
43044304
let remaining = paths.size;
43054305

43064306
return new Promise((resolve, reject) => {
4307+
if (remaining === 0) {
4308+
return settle();
4309+
}
4310+
43074311
for (const path of paths) {
43084312
const schemaType = schema.path(path);
43094313
if (schemaType == null) {
@@ -4328,13 +4332,17 @@ Model.validate = async function validate(obj, pathsOrOptions, context) {
43284332
}, context, { path: path });
43294333
}
43304334

4335+
function settle() {
4336+
if (error) {
4337+
reject(error);
4338+
} else {
4339+
resolve(obj);
4340+
}
4341+
}
4342+
43314343
function _checkDone() {
43324344
if (--remaining <= 0) {
4333-
if (error) {
4334-
reject(error);
4335-
} else {
4336-
resolve(obj);
4337-
}
4345+
return settle();
43384346
}
43394347
}
43404348
});

test/model.validate.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,28 @@ describe('model: validate: ', function() {
206206
assert.equal(err.errors['myNumber'].name, 'CastError');
207207
assert.equal(err.errors['invalid1'].name, 'ValidatorError');
208208
});
209+
210+
it('should return cast errors when validating only paths that fail casting', async function() {
211+
const Model = mongoose.model('Test', new Schema({
212+
validPath: {
213+
type: String,
214+
required: true
215+
},
216+
invalidPath1: {
217+
type: Number,
218+
required: true
219+
},
220+
invalidPath2: {
221+
type: Number,
222+
required: true
223+
}
224+
}));
225+
226+
const err = await Model.validate({ validPath: 'foo', invalidPath1: 'not a number', invalidPath2: 'not a number' }, ['invalidPath1', 'invalidPath2']).
227+
then(() => null, err => err);
228+
assert.ok(err);
229+
assert.deepEqual(Object.keys(err.errors).sort(), ['invalidPath1', 'invalidPath2']);
230+
assert.equal(err.errors['invalidPath1'].name, 'CastError');
231+
assert.equal(err.errors['invalidPath2'].name, 'CastError');
232+
});
209233
});

0 commit comments

Comments
 (0)