Skip to content

Commit

Permalink
Merge pull request #14161 from Automattic/vkarpov15/gh-14114
Browse files Browse the repository at this point in the history
fix(update): set CastError path to full path if casting update fails
  • Loading branch information
vkarpov15 committed Dec 24, 2023
2 parents 6d87344 + 6f7b659 commit 3bd67a8
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 10 deletions.
9 changes: 8 additions & 1 deletion lib/schema/bigint.js
Expand Up @@ -212,7 +212,14 @@ SchemaBigInt.prototype.castForQuery = function($conditional, val, context) {
return this.applySetters(null, val, context);
}

return this.applySetters(val, context);
try {
return this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
};

/**
Expand Down
9 changes: 8 additions & 1 deletion lib/schema/boolean.js
Expand Up @@ -256,7 +256,14 @@ SchemaBoolean.prototype.castForQuery = function($conditional, val, context) {
return this.applySetters(null, val, context);
}

return this.applySetters(val, context);
try {
return this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
};

/**
Expand Down
11 changes: 10 additions & 1 deletion lib/schema/buffer.js
Expand Up @@ -279,7 +279,16 @@ SchemaBuffer.prototype.castForQuery = function($conditional, val, context) {
}
return handler.call(this, val);
}
const casted = this.applySetters(val, context);

let casted;
try {
casted = this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
return casted ? casted.toObject({ transform: false, virtuals: false }) : casted;
};

Expand Down
9 changes: 8 additions & 1 deletion lib/schema/date.js
Expand Up @@ -407,7 +407,14 @@ SchemaDate.prototype.$conditionalHandlers = {

SchemaDate.prototype.castForQuery = function($conditional, val, context) {
if ($conditional == null) {
return this.applySetters(val, context);
try {
return this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
}

const handler = this.$conditionalHandlers[$conditional];
Expand Down
11 changes: 10 additions & 1 deletion lib/schema/number.js
Expand Up @@ -429,7 +429,16 @@ SchemaNumber.prototype.castForQuery = function($conditional, val, context) {
}
return handler.call(this, val, context);
}
val = this.applySetters(val, context);

try {
val = this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}

return val;
};

Expand Down
9 changes: 8 additions & 1 deletion lib/schema/string.js
Expand Up @@ -688,7 +688,14 @@ SchemaString.prototype.castForQuery = function($conditional, val, context) {
return val;
}

return this.applySetters(val, context);
try {
return this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
};

/*!
Expand Down
11 changes: 9 additions & 2 deletions lib/schema/uuid.js
Expand Up @@ -344,8 +344,15 @@ SchemaUUID.prototype.castForQuery = function($conditional, val, context) {
if (!handler)
throw new Error('Can\'t use ' + $conditional + ' with UUID.');
return handler.call(this, val, context);
} else {
return this.cast(val);
}

try {
return this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
};

Expand Down
9 changes: 8 additions & 1 deletion lib/schemaType.js
Expand Up @@ -1630,7 +1630,14 @@ SchemaType.prototype.castForQuery = function($conditional, val, context) {
return handler.call(this, val, context);
}

return this.applySetters(val, context);
try {
return this.applySetters(val, context);
} catch (err) {
if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
err.path = this.$fullPath;
}
throw err;
}
};

/**
Expand Down
30 changes: 30 additions & 0 deletions test/model.findOneAndUpdate.test.js
Expand Up @@ -2200,4 +2200,34 @@ describe('model: findOneAndUpdate:', function() {
);
assert.equal(updated.defaultField, 'some non-default value');
});

it('sets CastError path to full path (gh-14114)', async function() {
const testSchema = new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String,
accessories: [
{
isEnabled: Boolean,
additionals: [
{
k: String,
v: Number
}
]
}
]
});
const Test = db.model('Test', testSchema);
const err = await Test.findOneAndUpdate(
{},
{
$set: {
'accessories.0.additionals.0.k': ['test']
}
}
).then(() => null, err => err);
assert.ok(err);
assert.equal(err.name, 'CastError');
assert.equal(err.path, 'accessories.0.additionals.0.k');
});
});
4 changes: 3 additions & 1 deletion test/schema.select.test.js
Expand Up @@ -15,10 +15,12 @@ describe('schema select option', function() {

before(function() {
db = start();
mongoose.set('debug', true);
});

after(async function() {
await db.close();
mongoose.set('debug', false);
});

beforeEach(() => db.deleteModel(/.*/));
Expand Down Expand Up @@ -53,7 +55,7 @@ describe('schema select option', function() {
assert.equal(findByIdDocAgain.isSelected('name'), false);
assert.equal(findByIdDocAgain.isSelected('docs.name'), false);
assert.strictEqual(undefined, findByIdDocAgain.name);
const findUpdateDoc = await Test.findOneAndUpdate({ _id: doc._id });
const findUpdateDoc = await Test.findOneAndUpdate({ _id: doc._id }, { name: 'the excluded' });
assert.equal(findUpdateDoc.isSelected('name'), false);
assert.equal(findUpdateDoc.isSelected('docs.name'), false);
assert.strictEqual(undefined, findUpdateDoc.name);
Expand Down

0 comments on commit 3bd67a8

Please sign in to comment.