Node.js 改进mongoose验证错误处理

Node.js 改进mongoose验证错误处理,node.js,validation,mongoose,error-handling,ejs,Node.js,Validation,Mongoose,Error Handling,Ejs,我有以下带有所需验证的架构: var mongoose=require(“mongoose”); var验证器=要求(“验证器”); var userSchema=newmongoose.Schema( { 电邮:{ 类型:字符串, 必填:[true,“电子邮件是必填字段”], 特里姆:没错, 小写:true, 独一无二:没错, 验证(值){ 如果(!validator.isEmail(值)){ 抛出新错误(“请输入有效的电子邮件!”); } }, }, 密码:{ 类型:字符串, 必填:[tru

我有以下带有所需验证的架构:

var mongoose=require(“mongoose”);
var验证器=要求(“验证器”);
var userSchema=newmongoose.Schema(
{
电邮:{
类型:字符串,
必填:[true,“电子邮件是必填字段”],
特里姆:没错,
小写:true,
独一无二:没错,
验证(值){
如果(!validator.isEmail(值)){
抛出新错误(“请输入有效的电子邮件!”);
}
},
},
密码:{
类型:字符串,
必填:[true,“密码是必填字段”],
验证(值){
if(!validator.isLength(值,{min:6,max:1000})){
抛出错误(“密码长度应在6-1000之间”);
}
if(value.toLowerCase().includes(“密码”)){
抛出错误(
'密码不应包含关键字“password”!'
);
}
},
},
},
{
时间戳:对,
}
);
var User=mongoose.model('User',userSchema);
我通过以下途径发送post请求,通过表单传递电子邮件和密码:

router.post(“/user”),异步(req,res)=>{
试一试{
var user=新用户(请求主体);
等待user.save();
资源状态(200)。发送(用户);
}捕获(错误){
资源状态(400)。发送(错误);
}
});
module.exports=mongoose.model(“用户”,User);
每当我根据验证规则输入一个字段时,就会收到一条很长的错误消息,这是显而易见的。但是现在,我想改进错误处理,以便用户能够轻松地理解它。与其重定向到一般错误页面,我如何重定向到同一注册页面,并在错误字段附近显示提示错误的flash消息?同样在成功的时候,也应该做一些类似的事情,比如在顶部写一条绿色的闪光信息


我将ejs用于我的注册页面。

在catch块中,您可以检查错误是否为mongoose验证错误,并动态创建如下错误对象:

{
   "email": "test",
   "password": "abc"
}
router.post(“/user”),异步(req,res)=>{
试一试{
var user=新用户(请求主体);
等待user.save();
资源状态(200)。发送(用户);
}捕获(错误){
如果(error.name==“ValidationError”){
让错误={};
Object.key(error.errors).forEach((key)=>{
错误[key]=错误。错误[key]。消息;
});
返回res.status(400)。发送(错误);
}
res.status(500)。发送(“出错”);
}
});
当我们发送这样的请求主体时:

{
   "email": "test",
   "password": "abc"
}
答复如下:

{
    "email": "Please enter a valid E-mail!",
    "password": "Length of the password should be between 6-1000"
}

您可以像这样使用
validator
,而不是抛出错误:

password:{
    type:String,
    required:[true, "Password is a required field"],

validate: {
  validator: validator.isLength(value,{min:6,max:1000}),
  message: "Length of the password should be between 6-1000"
}
    }
你可以发送

res.status(400).send(error.message);
而不是:

res.status(400).send(error);
您还应该在模式中进行一些更改

validate(value){
            if (!validator.isEmail(value)) {
                throw new Error("Please enter a valid E-mail!");
            }
        }

密码:

minlength: 6,
maxlength:1000,
validate:{
validator: function(el){
return el.toLowerCase() !== "password"
}
message: 'The password should not contain the keyword "password"!'
}

谢谢这有帮助!另外,我如何在注册页面上显示flash消息等错误,并让用户再次填写表单?@MehulChaturvedi不客气,我没有使用ejs的经验,但我建议您首先将消息显示为简单标签。最好是一步一步地进行。还有一件事我会查看您的代码,您直接保存您的请求。用户集合中的body用户文档可能存在很大的安全漏洞。实际上,我在save()函数之前添加了一个预钩子,使用bcryptjs散列密码。这很好,但我写这篇评论的目的是:用户模式中可能有一些键,我们可能不想在用户创建帐户时保存,例如isAdmin,iPrime用户,甚至prfilepic,但如果有人在请求时点击api,这些密钥也将在创建时保存在用户文档中。这通常是我们不想要的…解决方案是什么?这将非常有用。replace:var user=newuser(req.body);with const data={email:req.body.email,password:req.body.password,anyOther:req.body.other};var user=新用户(数据)//代码的其余部分。此数据对象将在创建配置文件时丢弃clent传递的不需要的数据。。希望你明白我的意思