diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index 7891fa847e..618a8c547a 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -3835,6 +3835,7 @@ describe('schemas', () => { .then(done.fail) .catch(error => { expect(error.code).toEqual(Parse.Error.DUPLICATE_VALUE); + expect(error.message).toEqual('A duplicate value for a field with unique values was provided. Duplicate index: code_1 on collection test_UniqueIndexClass in db parseServerMongoAdapterTestDatabase') done(); }); }); diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 481d5257d9..8f674c21a2 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -26,6 +26,29 @@ const ReadPreference = mongodb.ReadPreference; const MongoSchemaCollectionName = '_SCHEMA'; + +// If we get a unique index error from mongo, try to parse it. If successful, return it. +const mongoUniqueIndexErrorFormatter = (message) => { + /** + * Sample error message that we are getting from mongo + * 'Plan executor error during findAndModify :: caused by :: E11000 duplicate key error collection: parseServerMongoAdapterTestDatabase.test_UniqueIndexClass index: code_1 dup key: { code: 2 }' + */ + const regex = /collection:\s*([\w-]+)\.([\w-]+)\s+index:\s*([\w-]+)/; + + const match = message.match(regex); + + if (match) { + const dbName = match[1]; + const collectionName = match[2]; + const indexName = match[3]; + // Adding extra starting space to make it more readable. + return ` Duplicate index: ${indexName} on collection ${collectionName} in db ${dbName}`; + } + + // Return nothing + return ''; +} + const storageAdapterAllCollections = mongoAdapter => { return mongoAdapter .connect() @@ -490,7 +513,7 @@ export class MongoStorageAdapter implements StorageAdapter { // Duplicate value const err = new Parse.Error( Parse.Error.DUPLICATE_VALUE, - 'A duplicate value for a field with unique values was provided' + `A duplicate value for a field with unique values was provided.${mongoUniqueIndexErrorFormatter(error.message)}` ); err.underlyingError = error; if (error.message) { @@ -575,7 +598,7 @@ export class MongoStorageAdapter implements StorageAdapter { if (error.code === 11000) { throw new Parse.Error( Parse.Error.DUPLICATE_VALUE, - 'A duplicate value for a field with unique values was provided' + `A duplicate value for a field with unique values was provided.${mongoUniqueIndexErrorFormatter(error.message)}` ); } throw error;