Created
April 14, 2012 15:15
-
-
Save boutell/2385154 to your computer and use it in GitHub Desktop.
Test: retrying save after a unique index error does not work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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? | |
* | |
* [email protected] 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