Skip to content

Commit

Permalink
fix(schema): make duplicate index error a warning for now to prevent …
Browse files Browse the repository at this point in the history
…blocking upgrading

Fix #15109
Re: #15112
  • Loading branch information
vkarpov15 committed Dec 27, 2024
1 parent 4081e5c commit b8d354f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
2 changes: 1 addition & 1 deletion lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -2148,7 +2148,7 @@ Schema.prototype.index = function(fields, options) {

for (const existingIndex of this.indexes()) {
if (options.name == null && existingIndex[1].name == null && isIndexSpecEqual(existingIndex[0], fields)) {
throw new MongooseError(`Schema already has an index on ${JSON.stringify(fields)}`);
utils.warn(`Duplicate schema index on ${JSON.stringify(fields)} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.`);
}
}

Expand Down
55 changes: 35 additions & 20 deletions test/schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const DocumentObjectId = mongoose.Types.ObjectId;
const vm = require('vm');
const idGetter = require('../lib/helpers/schema/idGetter');
const applyPlugins = require('../lib/helpers/schema/applyPlugins');
const utils = require('../lib/utils');

/**
* Test Document constructor.
Expand Down Expand Up @@ -3279,29 +3280,43 @@ describe('schema', function() {
assert.equal(subdoc.getAnswer(), 42);
});
it('throws "already has an index" error if duplicate index definition (gh-15056)', function() {
const ObjectKeySchema = new mongoose.Schema({
key: {
type: String,
required: true,
unique: true
},
type: {
type: String,
required: false
}
});
sinon.stub(utils, 'warn').callsFake(() => {});
try {
const ObjectKeySchema = new mongoose.Schema({
key: {
type: String,
required: true,
unique: true
},
type: {
type: String,
required: false
}
});

assert.throws(() => {
ObjectKeySchema.index({ key: 1 });
}, /MongooseError.*already has an index/);
assert.equal(utils.warn.getCalls().length, 1);
let [message] = utils.warn.getCalls()[0].args;
assert.equal(
message,
'Duplicate schema index on {"key":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.'
);

ObjectKeySchema.index({ key: 1, type: 1 });
assert.throws(() => {
ObjectKeySchema.index({ key: 1, type: 1 });
}, /MongooseError.*already has an index/);

ObjectKeySchema.index({ type: 1, key: 1 });
ObjectKeySchema.index({ key: 1, type: -1 });
ObjectKeySchema.index({ key: 1, type: 1 }, { unique: true, name: 'special index' });
assert.equal(utils.warn.getCalls().length, 1);
ObjectKeySchema.index({ key: 1, type: 1 });
assert.equal(utils.warn.getCalls().length, 2);
[message] = utils.warn.getCalls()[1].args;
assert.equal(
message,
'Duplicate schema index on {"key":1,"type":1} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.'
);

ObjectKeySchema.index({ type: 1, key: 1 });
ObjectKeySchema.index({ key: 1, type: -1 });
ObjectKeySchema.index({ key: 1, type: 1 }, { unique: true, name: 'special index' });
} finally {
sinon.restore();
}
});
});

0 comments on commit b8d354f

Please sign in to comment.