Skip to content

Instantly share code, notes, and snippets.

@boutell
Created April 14, 2012 15:15
Show Gist options
  • Save boutell/2385154 to your computer and use it in GitHub Desktop.
Save boutell/2385154 to your computer and use it in GitHub Desktop.
Test: retrying save after a unique index error does not work
/**
* Create a situation where a unique index error will occur. Try to save the
* object again after making the relevant field unique. Expected behavior:
* object saves second (or third...) time and we wind up with ten objects. Actual behavior:
* we get just one object and there is a unique index error after all ten save callbacks
* have already been invoked "successfully"! This is really strange, even stranger than I
* thought. Maybe the index is not applied yet somehow and I need to wait on the schema
* being ready?
*
* tom@punkave.com 2012-04-14
*/
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/mongooseRetrySaveTest');
var Schema = mongoose.Schema;
var mediaItemSchema = new Schema({
slug: { type: String, unique: true }
});
// Don't do anything until the ensureIndex() calls on the model are really complete
var MediaItem = mongoose.model('MediaItem', mediaItemSchema);
MediaItem.on('index', function()
{
console.log('got the index event from MediaItem');
cleanup();
});
function cleanup()
{
MediaItem.remove({}, function (err) {
if (err)
{
throw err;
}
console.log("Successfully cleaned up any previous test");
insert();
});
}
function insert()
{
for (i = 0; (i < 10); i++)
{
insertOne();
}
}
function insertOne()
{
var mediaItem = new MediaItem();
mediaItem.slug = "common-slug";
attemptSave(mediaItem);
}
function attemptSave(mediaItem)
{
mediaItem.save(afterSaveAttempt);
function afterSaveAttempt(err, savedItem)
{
console.log("in afterSaveAttempt");
if (err)
{
console.log("there is an error");
if ((err.code === 11000) && (err.err.indexOf('slug') !== -1))
{
console.log("Retrying with a more unique slug");
mediaItem.slug += (Math.floor(Math.random() * 10)).toString();
mediaItem.save(afterSaveAttempt);
return;
}
else
{
console.log("Throwing error");
throw err;
}
}
console.log(savedItem.id);
// No error - count it as a success
afterSaveSuccess();
}
}
var saved = 0;
function afterSaveSuccess()
{
console.log("Counting success");
saved++;
if (saved === 10)
{
find();
}
}
// We should have 100 items now, how many do we really have?
function find()
{
MediaItem.find({}, function(err, docs) {
console.log("We have " + docs.length + " objects, we expected 10");
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment