收到重复的电子邮件地址E11000重复键错误时,节点应用程序崩溃

时间:2018-02-02 11:25:37

标签: node.js

我已经查看了有关此错误的其他问题,并且提供的每个答案都有所不同。由于我的代码不同,其他人很难识别问题。当我运行我的节点应用程序并在电子邮件字段中输入重复的电子邮件并继续论坛请求时,服务器崩溃并抛出此错误:

BulkWriteError: E11000 duplicate key error collection: loginapp.users index: email_1 dup key:

这就是说,至少我认为这是说我输入的电子邮件已在数据库中使用。这是我想要的,但不是崩溃我宁愿让它发送消息到页面说“电子邮件已经存在”。我的代码低于任何帮助,或者正确的方向上的一点将不胜感激!

我唯一的想法是尝试catch来捕获错误,然后通知用户重复。如果这是正确的事情,我不能确定如何使用我当前的代码设置。

// Register
router.get('/register', function(req, res){
    res.render('register');
});

// Login
router.get('/login', function(req, res){
    res.render('login');
});

// Register User
router.post('/register', function(req, res){
    var firstname = req.body.firstname;
    var lastname = req.body.lastname;
    var email = req.body.email;
    var username = req.body.username;
    var password = req.body.password;
    var password2 = req.body.password2;

    // Validation
    req.checkBody('firstname', 'First Name is required').notEmpty();
    req.checkBody('lastname', 'Last Name is required').notEmpty();
    req.checkBody('email', 'Email is required').notEmpty();
    req.checkBody('email', 'Email is not valid').isEmail();
    req.checkBody('username', 'Username is required').notEmpty();
    req.checkBody('password', 'Password is required').notEmpty();
    req.checkBody('password2', 'Passwords do not match').equals(req.body.password);

    var errors = req.validationErrors();

    if(errors){
        res.render('register',{
            errors:errors
        });
    } else {
        var newUser = new User({
            firstname: firstname,
            lastname: lastname,
            email:email,
            username: username,
            password: password
        });

        User.createUser(newUser, function(err, user){
            if(err) throw err;
            console.log(user);
        });

        req.flash('success_msg', 'You are registered and can now login');

        res.redirect('/users/login');
    }
});

passport.use(new LocalStrategy(
  function(username, password, done) {
   User.getUserByUsername(username, function(err, user){
    if(err) throw err;
    if(!user){
        return done(null, false, {message: 'Unknown User'});
    }

    User.comparePassword(password, user.password, function(err, isMatch){
        if(err) throw err;
        if(isMatch){
            return done(null, user);
        } else {
            return done(null, false, {message: 'Invalid password'});
        }
    });
   });
  }));

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.getUserById(id, function(err, user) {
    done(err, user);
  });
});

router.post('/login',
  passport.authenticate('local', {successRedirect:'/', failureRedirect:'/users/login',failureFlash: true}),
  function(req, res) {
    res.redirect('/');
  });

router.get('/logout', function(req, res){
    req.logout();

    req.flash('success_msg', 'You are logged out');

    res.redirect('/users/login');
});

module.exports = router;

App.js

// Connect Flash
app.use(flash());

// Global Vars
app.use(function (req, res, next) {
  res.locals.success_msg = req.flash('success_msg');
  res.locals.error_msg = req.flash('error_msg');
  res.locals.error = req.flash('error');
  res.locals.user = req.user || null;
  next();
});

2 个答案:

答案 0 :(得分:2)

您已经在MongoDB用户集上创建了一个唯一索引,这就是为什么mongo会抛出此错误,并且无法轻松覆盖mongoose功能,因此您必须在代码中处理它。

在您的代码中,您正在抛出错误,但您并未在任何地方处理错误

User.createUser(newUser, function(err, user){
    if(err) throw err;  // <== this line
    console.log(user);
});

所以不要抛出错误,你可以在那里处理它。

但最好的处理方法是在注册之前先检查电子邮件,如果您不想这样做,请使用express的错误处理程序来处理错误。 当您使用默认快速路由器时,您将在参数中获得回调函数,因此利用它来编写常见错误处理程序

router.post('/register', function(req, res , next) {  // <== next function as callback
    // your code
    User.createUser(newUser, function(err, user){
        if(err) {
            if (err.code == 11000 && err.message.indexOf('users.$email_1') > -1) {
              next(new Error('DUP_EMAIL'));
            } else {
          next(new Error('INTERNAL_ERROR'));
            }
          }
        console.log(user);
    });
}

然后在你的app.js或server.js中,无论你的主要表达文件如何编写以下函数来处理错误

app.use('/', indexRoutes);  // router

// catch 404 and forward to error handler
app.use((request, response, next) => {
    // response.status(404).send('NOT_FOUND');
});

// other type of errors, it *might* also be a Runtime Error
app.use((err, request, response, next) => {
    // your logic to send error
  req.flash('error_msg', mappingFile[err.message]); // mapping file is key value pair of code and user friendly messages
});

答案 1 :(得分:0)

  

在你的代码中,你抛出一个错误。永远不会抛出错误而是处理   代码中的错误以防止服务器崩溃。

这样处理。

 User.createUser(newUser, function(err, user) {
     if (err) {
         if (err.code == 11000 && err.message.indexOf('users.$phoneNo_1') > -1) {

             // your custom logic here

         } else if (err.code == 11000 && err.message.indexOf('users.$email_1') > -1) {

             // your custom logic here
         } else {
             // your custom logic here
         }
     } else {
         // your custom logic here
     }

 });