MongoDB预保存钩子:条件不满足时如何取消RegUser保存
解决方案
一、预保存钩子中取消保存的方法
在预保存钩子的else分支里,给done回调传入一个错误对象即可,Mongoose会自动终止当前保存操作并抛出该错误:
regUserSchema.pre('save', async function(done) { // 先处理邮箱格式异常,避免split后取[1]报错 const emailParts = this.email.split('@'); if (emailParts.length !== 2) { return done(new Error('邮箱格式不正确')); } const domain = emailParts[1]; const exists = await Firm.findOne({ domain }); if (exists) { done(); } else { done(new Error('该邮箱域名未在Firm集合中注册')); } });
如果用的是新版Mongoose,也可以直接抛出错误,不用依赖done回调:
regUserSchema.pre('save', async function() { const emailParts = this.email.split('@'); if (emailParts.length !== 2) { throw new Error('邮箱格式不正确'); } const domain = emailParts[1]; const exists = await Firm.findOne({ domain }); if (!exists) { throw new Error('该邮箱域名未在Firm集合中注册'); } });
二、更优实现:使用Mongoose自定义验证器
相比预保存钩子,字段自定义验证器更贴合验证场景,代码逻辑更清晰,还能和其他验证规则(比如邮箱格式校验)整合:
regUserSchema.path('email').validate(async function(email) { const emailParts = email.split('@'); if (emailParts.length !== 2) { return false; } const domain = emailParts[1]; const exists = await Firm.findOne({ domain }); return !!exists; }, '该邮箱域名未在Firm集合中注册');
当邮箱域名不存在时,验证会直接失败,Mongoose自动阻止保存操作,并返回你定义的错误信息。
内容的提问来源于stack exchange,提问作者melv3223
相关产品推荐
相关产品推荐

