Mongoose动态验证错误消息实现:RecipeSchema的HTML字段验证
Mongoose异步验证:将HTML验证错误作为自定义消息
你的问题核心在于Mongoose同步验证器无法处理异步操作,而且没法直接把异步获取的错误消息绑定到静态的message字段上。咱们一步步解决这个问题:
原代码的问题
htmlValidator是异步的(返回Promise),但你的validator函数是同步执行的——函数会直接返回初始的isValid = false,完全等不及异步验证的结果。- 静态的
message字段无法动态获取异步返回的错误信息,所以只能显示固定文本。
解决方案:使用Mongoose异步验证器
Mongoose支持异步验证,只需要在validate配置里加上async: true,然后让validator函数返回Promise(或者用async/await语法),验证失败时抛出包含具体错误的Error即可。
修正后的完整代码
const RecipeSchema = new Schema({ instructions: { type: String, validate: { // 标记为异步验证器 async: true, // 使用async/await简化异步逻辑 validator: async function(instructions) { const options = { data: instructions, ignore: [ 'Error: Element “head” is missing a required instance of child element “title”.', 'Error: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.', ], }; // 等待HTML验证结果 const validationResult = await htmlValidator(options); // 验证通过:返回true if (validationResult === 'The document validates according to the specified schema(s).') { return true; } // 验证失败:抛出包含具体错误的Error,Mongoose会自动用这个作为错误消息 throw new Error(validationResult); }, // 可选:设置默认格式化消息,props.reason会拿到抛出的错误内容 message: props => `HTML验证失败:${props.reason}` }, required: 'Please enter some instructions for this recipe', }, });
关键细节说明
async: true:必须添加这个配置,告诉Mongoose要等待验证器的异步操作完成。async/await:替代回调函数,让异步代码看起来像同步代码,更易读。- 抛出错误:当HTML验证不通过时,直接抛出带有
validationResult的Error,Mongoose会自动将这个错误的message作为该字段的验证错误消息。 - 错误消息的使用:当你保存文档失败时,可以通过
err.errors.instructions.message获取到具体的HTML验证错误,比如:recipe.save().catch(err => { console.log(err.errors.instructions.message); // 输出示例:Error: Element 'p' is missing a closing tag. });
替代方案:直接返回Promise
如果你不习惯async/await,也可以直接返回Promise:
validator: function(instructions) { const options = { data: instructions, ignore: [ 'Error: Element “head” is missing a required instance of child element “title”.', 'Error: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.', ], }; return htmlValidator(options).then(validationResult => { if (validationResult === 'The document validates according to the specified schema(s).') { return Promise.resolve(); } // 验证失败,reject并传递错误消息 return Promise.reject(new Error(validationResult)); }); }
注意事项
- 确保你使用的
html-validator版本支持Promise(从你的代码来看已经在使用.then,所以没问题)。 - 忽略的错误字符串要和
htmlValidator返回的内容完全匹配,否则不会被忽略。 - 如果
htmlValidator返回的是错误数组(而不是字符串),你需要调整逻辑,比如将错误数组拼接成字符串再抛出。
内容的提问来源于stack exchange,提问作者Julian Betancourt
相关产品推荐
相关产品推荐

