You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose动态验证错误消息实现:RecipeSchema的HTML字段验证

Mongoose异步验证:将HTML验证错误作为自定义消息

你的问题核心在于Mongoose同步验证器无法处理异步操作,而且没法直接把异步获取的错误消息绑定到静态的message字段上。咱们一步步解决这个问题:

原代码的问题

  1. htmlValidator是异步的(返回Promise),但你的validator函数是同步执行的——函数会直接返回初始的isValid = false,完全等不及异步验证的结果。
  2. 静态的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:32:35