如何在插入违反唯一索引的MongoDB文档时捕获错误?

时间:2015-06-02 10:45:50

标签: javascript mongodb express mongoose mean

我正在构建一个MEAN应用程序。

这是我的用户名架构,用户名应该是唯一的。

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

module.exports = mongoose.model('User', new Schema({ 
    username: { type: String, unique: true }
}));

在我的帖子路线上,我像这样保存用户:

app.post('/authenticate', function(req, res) {
        var user = new User({
            username: req.body.username
        });

        user.save(function(err) {
            if (err) throw err;

            res.json({
                success: true
            });

        });
    })

如果我再次使用相同的用户名发布,我会收到此错误:

  

MongoError:insertDocument ::由:: 11000 E11000重复密钥引起   错误索引:

有人可以解释如何发送像{ succes: false, message: 'User already exist!' }

这样的json而不是错误

注意:发布用户后,我会自动验证,不需要密码或其他内容。

4 个答案:

答案 0 :(得分:35)

您需要测试从save方法返回的错误,以查看是否为重复的用户名抛出了该错误。

app.post('/authenticate', function(req, res) {
  var user = new User({
    username: req.body.username
  });

  user.save(function(err) {
    if (err) {
      if (err.name === 'MongoError' && err.code === 11000) {
        // Duplicate username
        return res.status(500).send({ succes: false, message: 'User already exist!' });
      }

      // Some other error
      return res.status(500).send(err);
    }

    res.json({
      success: true
    });

  });
})

答案 1 :(得分:3)

你也可以试试这个漂亮的软件包 mongoose-unique-validator ,这样可以更轻松地处理错误,因为当你试图违反一个独特的约束时,你会得到一个Mongoose验证错误,而不是来自MongoDB的E11000错误:

var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');

// Define your schema as normal.
var userSchema = mongoose.Schema({
    username: { type: String, required: true, unique: true }
});

// You can pass through a custom error message as part of the optional options argument:
userSchema.plugin(uniqueValidator, { message: '{PATH} already exists!' });

答案 2 :(得分:2)

试试这个:

app.post('/authenticate', function(req, res) {
        var user = new User({
            username: req.body.username
        });

        user.save(function(err) {
            if (err) {
                // you could avoid http status if you want. I put error 500 
                return res.status(500).send({
                    success: false,
                    message: 'User already exist!'
                });
            }

            res.json({
                success: true
            });

        });
    })

答案 3 :(得分:0)

以下是使用类型错误而不是字符串来验证它的方法:

const { MongoError } = require('mongodb')

async createUser(userJSON) {
  try {
    return await User.create(userJSON)
  } catch (e) {
    if (e instanceof MongoError) {
      throw new Error('Username already exist')
    }
    throw new Error('Something went wrong!')
  }
}