2012-09-24 19 views
10

He creado un formulario de registro utilizando mangosta y expresar 3cómo recuperarse de clave duplicada en mangosta + expresan

Su posible que el usuario ya existe con ese nombre de usuario, en cuyo caso me sale un err.code 11000 (llave duplicada). ¿Cómo debo manejar a los usuarios existentes?

Esto es lo que estoy haciendo ahora .... pero no estoy seguro de código de comprobación de error es de mejor manera:

user.save(function(err){ 
    if (err) { 
     console.log(err); 
     console.log(err.code); 

     //duplicate key 
     if (err.code == 11000) { 
     req.flash('error', 'User already exists'); 
     res.redirect('/signup'); 
     return; 
     } 
    } 

    res.locals.user = user; 
    req.session.user = user; 
    //res.locals.session = req.session; 
    res.redirect('/'); 
    }); 

¿Hay una mejor manera de hacer esto?

+0

se ve bastante limpio. ¿Qué cosa en particular no te parece bien? – JohnnyHK

+0

Solo el hecho de que dejo que el db arroje un error en lugar de buscar primero al usuario. – chovy

+0

Depende de qué haría que otra solución sea "una mejor manera" en su situación. ¿No intenta ser difícil, pero si esto es funcionalmente correcto y su rendimiento es adecuado y es mantenible ...? – JohnnyHK

Respuesta

3

No he probado esto todavía, pero esto es lo que estoy pensando evitará que se genere un error:

//look for existing user first 
user.findOne({ username: req.body.username }, function(err, user) { 
    if (err) throw err; 

    //existing user found, stop registration 
    if (user) { 
     res.flash('error', "That user already exists"); 
     res.redirect('/signup'); 
     return; 
    } 

    //create new user 
    var user = new User({ username: req.body.username }); 

    user.save(function(err){ 
    if (err) throw err; 
     res.flash('info', "Your account has been created"); 
     res.redirect('/account'); 
    }); 
}); 
+0

También puede usar '.count()' que es un poco más sucinto/memorable pero no permite el uso de los datos devueltos si es necesario. –

+0

Ps, creo que la mangosta debería tener algo como 'Model.saveUnique ({username: req.body.username}, function (err) {...});' –

+0

En realidad, es más seguro manejar el error duplicado de la llave porque es posible que otra solicitud haya creado al usuario entre 'user.findOne()' lee la colección y 'user.save()' se ejecuta. Es decir, hay una condición de carrera en la que su API podría arrojar un error 5xx. Para un formulario en el que se espera que el usuario no exista, intentar guardarlo y luego manejar un error anticipado de DuplicateKey es menos código (no es necesario 'user.findOne()') y evita esta condición de carrera. Si espera que la entidad ya exista, podría ser más natural intentar cargarla primero. – binki

13

Prueba esto:

user.save(function(err){ 
    if (err && err.code !== 11000) { 
    console.log(err); 
    console.log(err.code); 
    res.send('Another error showed up'); 
    return; 
    } 

    //duplicate key 
    if (err && err.code === 11000) { 
    req.flash('error', 'User already exists'); 
    res.redirect('/signup'); 
    return; 
    } 

    res.locals.user = user; 
    req.session.user = user; 
    //res.locals.session = req.session; 
    res.redirect('/'); 
}); 

Usted no va a llenar el registro de errores de esta manera.

+0

¿No es eso lo que tenía? ¿Cuál es la diferencia? y los errores se muestran en el registro independientemente ... no estoy seguro de cómo esto es diferente. – chovy

+0

Lo siento @chovy, modifiqué mi respuesta un poco. - El primer condicionamiento ocurrirá en caso de que el error no sea un error de "clave duplicada" y devuelva 'Otro error apareció' al cliente. - Se producirá la segunda condición en caso de que el error sea un error de "clave duplicada". - Si no hay error, la secuencia de comandos irá según las instrucciones. – red

+0

Ya veo, gracias. Todavía creo que se registraron errores, ya que la consulta arrojó un error. Podría hacer user.findOne (.., function (err, user) {if (! User) new User(); user.save()}); – chovy

Cuestiones relacionadas