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

如何为Express Validator的Schema验证设置自定义错误消息?

Fixing Custom Error Messages in express-validator checkSchema with Async Validations

Hey there! Let's sort out those mixed-up error messages in your express-validator setup. The root problem here is that you're using a single global errorMessage for each field, but every validation rule—including your async checks for duplicate emails/usernames—needs its own specific error message to avoid cross-over.

Why Your Current Setup Is Failing

When you set a top-level errorMessage on a field, it acts as a fallback for all validation failures on that field. If you don't define individual messages for rules like isEmail, notEmpty, or your async custom checks, every failure (whether it's a bad email format or a duplicate entry) will default to that one message. That's why you're seeing "This email is already in use" even when the DNS validation fails.

Corrected Validation Schema Example

Here's how to update your schema to assign specific messages to each rule. I'll include fixes for email and username (since those were your main pain points) along with your existing fields:

const { checkSchema } = require('express-validator');

const validation_rules = checkSchema({
  company_name: {
    trim: true,
    isLength: {
      options: { min: 3, max: 50 },
      errorMessage: 'Company Name should be at least 3 chars long and maximum of 50 chars'
    }
  },
  profile_name: {
    trim: true,
    isLength: {
      options: { min: 3, max: 50 },
      errorMessage: 'Public Profile Name should be at least 3 chars long and maximum of 50 chars'
    }
  },
  description: {
    trim: true,
    isLength: {
      options: { min: 2, max: 200 },
      errorMessage: 'Company Description should be at least 2 chars long and maximum of 200 chars'
    }
  },
  company_street_address: {
    trim: true,
    isLength: {
      options: { min: 3, max: 100 },
      errorMessage: 'Company Address should be at least 3 chars long and maximum of 100 chars'
    }
  },
  // Fixed Email Validation
  email: {
    trim: true,
    isEmail: {
      options: {
        require_tld: true // Ensures DNS validation for the email domain
      },
      errorMessage: 'Not a valid email' // Triggers when format/DNS fails
    },
    custom: {
      options: async (value) => {
        // Replace with your actual duplicate check logic
        const existingUser = await User.findOne({ email: value });
        if (existingUser) {
          throw new Error('This email is already in use');
        }
      },
      errorMessage: 'This email is already in use' // Triggers when email is taken
    }
  },
  // Fixed Username Validation
  username: {
    trim: true,
    notEmpty: {
      errorMessage: 'Please enter username' // Triggers when username is empty
    },
    isLength: {
      options: { max: 25 },
      errorMessage: 'Username cannot exceed 25 characters' // Triggers when too long
    },
    custom: {
      options: async (value) => {
        // Replace with your actual duplicate check logic
        const existingUser = await User.findOne({ username: value });
        if (existingUser) {
          throw new Error('This username is already in use');
        }
      },
      errorMessage: 'This username is already in use' // Triggers when username is taken
    }
  }
});

Key Changes Explained

  1. Per-Rule Error Messages: Each validation rule (isLength, isEmail, notEmpty, custom) now has its own errorMessage. This ensures each failure scenario returns the correct message.
  2. Async Custom Checks: For your duplicate checks, the custom rule gets its own errorMessage (and we also throw an explicit error inside the async function, which acts as a backup).
  3. Removed Top-Level Field Error Messages: Instead of a global message for the field, each rule defines its own, so there's no fallback that overrides specific messages.

Verifying Error Messages

Make sure you're collecting errors correctly in your route handler using validationResult:

const { validationResult } = require('express-validator');

app.post('/your-endpoint', validation_rules, (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
  // Proceed with your logic
});

Each entry in errors.array() will have a msg property matching the specific rule's error message that failed.

内容的提问来源于stack exchange,提问作者Mohsin Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:49:00