Andrey
Andrey

Reputation: 21285

Better ways to handle MongoDB exceptions

I am working on a MongoDB-backed authentication module for my asp.net application. The MongoDB database has a collections of users where I store login information - username, email and password. Both username and email are set to be unique:

users.ensureIndex({email:1}, {unique:1})
users.ensureIndex({uname:1}, {unique:1})

Now, if I try to insert a record with existing uname or email, i get a MongoDB exception:

Safemode detected an error: E11000 duplicate key error index: 
authdb.users.$email_1  dup key: { : "[email protected]" } 
(response: { "err" : "E11000 duplicate key error index: authdb.users.$email_1  
dup key: { : \"[email protected]\" }", "code" : 11000, "n" : 0, "connectionId" : 9, 
"ok" : 1.0 })

I need to tell the user that the username or email they entered already exists, but the whole exception is just a blob of text, and to see what's going on I have to guess by looking whether "$email" or "$uname" are in the error message text. Is there some sort of parser for MongoDB exceptions which would help me detect what the exception is for?

Upvotes: 9

Views: 13333

Answers (2)

KCD
KCD

Reputation: 10281

With c# MongoDB driver 1.x a duplicate can be detected like so

try
{
    collection.Insert(doc);
}
catch (MongoWriteConcernException ex)
{
    if (ex.Code == 11000)
        throw new YourConflictException("User already exists for username and/or email");
    else
        throw ex;
}

With c# MongoDB driver 2.x see https://stackoverflow.com/a/30309874/516748

But if you want to know exactly which duplicate key you may need to parse the text

Upvotes: 5

mstearn
mstearn

Reputation: 4276

I have created a feature request in MongoDB's bug tracker to add extra fields to the output of getLastError on duplicate key errors. Please vote for it at https://jira.mongodb.org/browse/SERVER-3069.

Until that is implemented, for your use case you can just check if the err string contains either "email" or "uname" and retrieve the duplicated value from the document you just tried to insert. It's not as elegant as it could be, but it should work for now.

Upvotes: 7

Related Questions