如何从mongoose + express中的重复键中恢复

cho*_*ovy 12 javascript mongoose node.js express

我使用mongoose和express 3创建了一个注册表单

用户可能已存在该用户名,在这种情况下,我得到一个err.code 11000(重复键).我该如何处理现有用户?

这就是我现在正在做的......但我不确定检查错误代码是最好的方法:

  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('/');
  });
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?

red*_*red 17

试试这个:

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('/');
});
Run Code Online (Sandbox Code Playgroud)

您不会以这种方式填写错误日志.


cho*_*ovy 5

我还没有尝试过这个,但这是我认为可以避免导致错误的方法:

//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');
  });
});
Run Code Online (Sandbox Code Playgroud)

  • 处理重复键错误实际上更安全,因为在 `user.findOne()` 读取集合和 `user.save()` 执行之间可能有另一个请求创建了用户。即,存在竞争条件,您的 API 可能会抛出 5xx 错误。对于您期望用户不存在的表单,只需尝试保存它然后处理预期的 DuplicateKey 错误就可以减少代码(不需要`user.findOne()`)并避免这种竞争条件。如果您希望实体已经存在,那么首先尝试加载它可能更自然。 (3认同)