Skip to content

Commit 26375d6

Browse files
committed
Merge branch 'master' into 8.4
2 parents 72d877d + cdedde6 commit 26375d6

File tree

4 files changed

+87
-7
lines changed

4 files changed

+87
-7
lines changed

lib/document.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -3831,16 +3831,14 @@ Document.prototype.$toObject = function(options, json) {
38313831
// need the original options the user passed in, plus `_isNested` and
38323832
// `_parentOptions` for checking whether we need to depopulate.
38333833
const cloneOptions = {
3834+
...options,
38343835
_isNested: true,
38353836
json: json,
38363837
minimize: _minimize,
38373838
flattenMaps: flattenMaps,
38383839
flattenObjectIds: flattenObjectIds,
38393840
_seen: (options && options._seen) || new Map(),
3840-
_calledWithOptions: options._calledWithOptions,
3841-
virtuals: options.virtuals,
3842-
getters: options.getters,
3843-
depopulate: options.depopulate
3841+
_calledWithOptions: options._calledWithOptions
38443842
};
38453843

38463844
const depopulate = options.depopulate ||

lib/model.js

+16
Original file line numberDiff line numberDiff line change
@@ -3264,6 +3264,14 @@ Model.$__insertMany = function(arr, options, callback) {
32643264

32653265
// Quickly escape while there aren't any valid docAttributes
32663266
if (docAttributes.length === 0) {
3267+
if (throwOnValidationError) {
3268+
return callback(new MongooseBulkWriteError(
3269+
validationErrors,
3270+
results,
3271+
null,
3272+
'insertMany'
3273+
));
3274+
}
32673275
if (rawResult) {
32683276
const res = {
32693277
acknowledged: true,
@@ -3623,6 +3631,14 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
36233631
validOps = validOps.sort().map(index => ops[index]);
36243632

36253633
if (validOps.length === 0) {
3634+
if (options.throwOnValidationError && validationErrors.length) {
3635+
throw new MongooseBulkWriteError(
3636+
validationErrors,
3637+
results,
3638+
res,
3639+
'bulkWrite'
3640+
);
3641+
}
36263642
return getDefaultBulkwriteResult();
36273643
}
36283644

test/document.test.js

+28
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,34 @@ describe('document', function() {
520520
docs.toObject({ transform: true });
521521
});
522522

523+
it('propagates toObject transform function to all subdocuments (gh-14589)', async function() {
524+
const schema = new mongoose.Schema({
525+
name: String,
526+
docArr: [{ name: String }],
527+
subdoc: new mongoose.Schema({ name: String })
528+
});
529+
const TestModel = db.model('Test', schema);
530+
531+
const doc = new TestModel({
532+
name: 'test',
533+
docArr: [{ name: 'test' }],
534+
subdoc: { name: 'test' }
535+
});
536+
537+
// pass the transform as an inline option. Deletes `_id` property
538+
// from both the top-level document and the subdocument.
539+
const obj = doc.toObject({ transform: deleteId });
540+
541+
assert.equal(obj._id, undefined);
542+
assert.equal(obj.subdoc._id, undefined);
543+
assert.equal(obj.docArr[0]._id, undefined);
544+
545+
function deleteId(doc, ret) {
546+
delete ret._id;
547+
return ret;
548+
}
549+
});
550+
523551
it('disabling aliases in toObject options (gh-7548)', function() {
524552
const schema = new mongoose.Schema({
525553
name: {

test/model.test.js

+41-3
Original file line numberDiff line numberDiff line change
@@ -4062,7 +4062,32 @@ describe('Model', function() {
40624062
assert.ok(doc.createdAt.valueOf() >= now.valueOf());
40634063
assert.ok(doc.updatedAt);
40644064
assert.ok(doc.updatedAt.valueOf() >= now.valueOf());
4065+
});
4066+
4067+
it('throwOnValidationError (gh-14572)', async function() {
4068+
const schema = new Schema({
4069+
num: Number
4070+
});
4071+
4072+
const M = db.model('Test', schema);
4073+
4074+
const ops = [
4075+
{
4076+
insertOne: {
4077+
document: {
4078+
num: 'not a number'
4079+
}
4080+
}
4081+
}
4082+
];
40654083

4084+
const err = await M.bulkWrite(
4085+
ops,
4086+
{ ordered: false, throwOnValidationError: true }
4087+
).then(() => null, err => err);
4088+
assert.ok(err);
4089+
assert.equal(err.name, 'MongooseBulkWriteError');
4090+
assert.equal(err.validationErrors[0].errors['num'].name, 'CastError');
40664091
});
40674092

40684093
it('with child timestamps and array filters (gh-7032)', async function() {
@@ -6602,14 +6627,14 @@ describe('Model', function() {
66026627
});
66036628

66046629
it('insertMany should throw an error if there were operations that failed validation, ' +
6605-
'but all operations that passed validation succeeded (gh-13256)', async function() {
6630+
'but all operations that passed validation succeeded (gh-14572) (gh-13256)', async function() {
66066631
const userSchema = new Schema({
66076632
age: { type: Number }
66086633
});
66096634

66106635
const User = db.model('User', userSchema);
66116636

6612-
const err = await User.insertMany([
6637+
let err = await User.insertMany([
66136638
new User({ age: 12 }),
66146639
new User({ age: 12 }),
66156640
new User({ age: 'NaN' })
@@ -6623,7 +6648,20 @@ describe('Model', function() {
66236648
assert.ok(err.results[2] instanceof Error);
66246649
assert.equal(err.results[2].errors['age'].name, 'CastError');
66256650

6626-
const docs = await User.find();
6651+
let docs = await User.find();
6652+
assert.deepStrictEqual(docs.map(doc => doc.age), [12, 12]);
6653+
6654+
err = await User.insertMany([
6655+
new User({ age: 'NaN' })
6656+
], { ordered: false, throwOnValidationError: true })
6657+
.then(() => null)
6658+
.catch(err => err);
6659+
6660+
assert.ok(err);
6661+
assert.equal(err.name, 'MongooseBulkWriteError');
6662+
assert.equal(err.validationErrors[0].errors['age'].name, 'CastError');
6663+
6664+
docs = await User.find();
66276665
assert.deepStrictEqual(docs.map(doc => doc.age), [12, 12]);
66286666
});
66296667

0 commit comments

Comments
 (0)