猫鼬唯一验证器触发服务器错误
Mongoose Unique Validator Triggers Server Error
我有一个 slug
属性,我将其设置为与 Mongoose 唯一:
// Article
var Article = new Schema({
title: { type: String, required: true },
heading: { type: String },
body: { type: String, required: true },
is_premium: { type: Boolean, required: true },
urlslug: { type: String, unique: true, required: true },
images: [Images],
videos: [Videos],
user: {
user_id: { type: String, required: true },
url: { type: String, required: true }
},
modified: { type: Date, required: true }
});
Article.path('title').validate(function (v) {
return v.length > 5 && v.length < 70;
});
我像这样成功地将它发布到数据库中:
router.post('/', passport.authenticate('bearer', { session: false }), function (req, res) {
if (req.user.role === "editor" || req.user.role === "moderator" || req.user.role === "admin") {
var article = new ArticleModel({
title: req.body.title,
heading: req.body.heading,
body: req.body.body,
images: req.body.images,
videos: req.body.videos,
is_premium: req.body.is_premium,
urlslug: req.body.slug,
modified: Date.now(),
user: {
user_id: req.user.id,
url: userUrlPrefix + req.user.username
}
});
article.save(function (err) {
if (!err) {
log.info("article created");
return res.send({ status: 'OK', article:article });
} else {
console.log(err);
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
log.error('Internal error(%d): %s',res.statusCode,err.message);
}
});
} else {
return res.send('your user can\'t create content');
}
});
当我尝试再次使用同一个 slug 并理想地触发验证错误时,我收到了服务器错误,而不是验证错误:
HTTP/1.1 500 Internal Server Error
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 24
Content-Type: application/json; charset=utf-8
Date: Fri, 30 Jan 2015 23:07:56 GMT
Vary: Origin
X-Powered-By: Express
{
"error": "Server error"
}
(我的节点控制台的输出):
{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error
index: SSR.articles.$urlslug_1 dup key: { : "article-1" }]
name: 'MongoError',
code: 11000,
err: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: SSR.articles.$urlslug_1 dup key: { : "article-1" }' }
error: [routes/articles.js] Internal error(500): insertDocument :: caused by :: 11000 E11000 duplicate key error index: SSR.articles.$urlslug_1 dup key: { : "article-1" }
Mongoose 中的验证是否没有明确的唯一性?如果没有,我如何使用 Mongoose 的 validate()
方法检查是否已经存在(滚动我自己的唯一验证器)?
您可以创建自己的 custom validator 来检查重复,但您仍然需要处理 E11000 重复键错误情况,因为在验证和插入之间仍可能发生另一个插入。因此,通常最好只使用 E11000 错误,这样您的重复错误处理就在一个地方。
您可以使用如下方法:
article.save(function (err) {
if (!err) {
log.info("article created");
return res.send({ status: 'OK', article:article });
} else {
console.log(err);
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else if (err.name == 'MongoError' && err.code == 11000) {
res.statusCode = 400;
res.send({ error: 'Duplicate validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
log.error('Internal error(%d): %s',res.statusCode,err.message);
}
});
我有一个 slug
属性,我将其设置为与 Mongoose 唯一:
// Article
var Article = new Schema({
title: { type: String, required: true },
heading: { type: String },
body: { type: String, required: true },
is_premium: { type: Boolean, required: true },
urlslug: { type: String, unique: true, required: true },
images: [Images],
videos: [Videos],
user: {
user_id: { type: String, required: true },
url: { type: String, required: true }
},
modified: { type: Date, required: true }
});
Article.path('title').validate(function (v) {
return v.length > 5 && v.length < 70;
});
我像这样成功地将它发布到数据库中:
router.post('/', passport.authenticate('bearer', { session: false }), function (req, res) {
if (req.user.role === "editor" || req.user.role === "moderator" || req.user.role === "admin") {
var article = new ArticleModel({
title: req.body.title,
heading: req.body.heading,
body: req.body.body,
images: req.body.images,
videos: req.body.videos,
is_premium: req.body.is_premium,
urlslug: req.body.slug,
modified: Date.now(),
user: {
user_id: req.user.id,
url: userUrlPrefix + req.user.username
}
});
article.save(function (err) {
if (!err) {
log.info("article created");
return res.send({ status: 'OK', article:article });
} else {
console.log(err);
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
log.error('Internal error(%d): %s',res.statusCode,err.message);
}
});
} else {
return res.send('your user can\'t create content');
}
});
当我尝试再次使用同一个 slug 并理想地触发验证错误时,我收到了服务器错误,而不是验证错误:
HTTP/1.1 500 Internal Server Error
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 24
Content-Type: application/json; charset=utf-8
Date: Fri, 30 Jan 2015 23:07:56 GMT
Vary: Origin
X-Powered-By: Express
{
"error": "Server error"
}
(我的节点控制台的输出):
{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error
index: SSR.articles.$urlslug_1 dup key: { : "article-1" }]
name: 'MongoError',
code: 11000,
err: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index: SSR.articles.$urlslug_1 dup key: { : "article-1" }' }
error: [routes/articles.js] Internal error(500): insertDocument :: caused by :: 11000 E11000 duplicate key error index: SSR.articles.$urlslug_1 dup key: { : "article-1" }
Mongoose 中的验证是否没有明确的唯一性?如果没有,我如何使用 Mongoose 的 validate()
方法检查是否已经存在(滚动我自己的唯一验证器)?
您可以创建自己的 custom validator 来检查重复,但您仍然需要处理 E11000 重复键错误情况,因为在验证和插入之间仍可能发生另一个插入。因此,通常最好只使用 E11000 错误,这样您的重复错误处理就在一个地方。
您可以使用如下方法:
article.save(function (err) {
if (!err) {
log.info("article created");
return res.send({ status: 'OK', article:article });
} else {
console.log(err);
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else if (err.name == 'MongoError' && err.code == 11000) {
res.statusCode = 400;
res.send({ error: 'Duplicate validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
log.error('Internal error(%d): %s',res.statusCode,err.message);
}
});