【问题标题】:How do I send more than one error at a time when validating?验证时如何一次发送多个错误?
【发布时间】:2023-03-03 02:49:01
【问题描述】:

当我创建 POST 请求时,我需要验证以下字段:first_name、last_name、mobile_number、reservation_date、reservation_time 和 people(party size)。

现在我有一个中间件函数来检查是否缺少任何字段:

function hasProperties(...properties) {
  return function (res, req, next) {
    const { data = {} } = res.body;

    try {
      properties.forEach((property) => {
        if (!data[property]) {
          const error = new Error(`${property}`);
          error.status = 400;
          throw error;
        }
      });
      next();
    } catch (error) {
      next(error);
    }
  };
}

然后在我的控制器中:

const hasAllProps = hasProperties(
  'first_name',
  'last_name',
  'mobile_number',
  'reservation_date',
  'reservation_time',
  'people'
);

这很好用,但是我必须为几个字段添加额外的验证。我有 2 个附加功能:一个是确保 people 字段是一个数字,另一个是确保 reservation_date 是一个日期:

const validPeople = (req, res, next) => {
  const { people } = req.body;
  if (Number.isInteger(people)) {
    return next();
  }
  next({ status: 400, message: 'people' });
};

const validDate = (req, res, next) => {
  const { reservation_date } = req.body;
  if (reservation_date instanceof Date) {
    return next();
  }
  next({ status: 400, message: 'reservation_date' });
};

然后我将它们全部传递给我的导出:

create: [hasAllProps, validDate, validPeople]

我一次只能发送一个错误,在本例中是它的validDate,因为它在exports 数组中的validPeople 之前。我无法将所有错误都放入数组中,因为我需要回复:

status: 400, message: '<the-specific-field>'

有没有办法单独发送所有这些错误消息?

【问题讨论】:

    标签: javascript node.js rest express validation


    【解决方案1】:

    正如其他回复所述,如果您尝试发送多个回复,这是不可能的。但是,您可以构造一个错误数组。

    从技术上讲,您可以在中间件之间传递数据... (Can I send data via express next() function?)

    ...但我的建议是尝试将它们合并到一个中间件中。例如,hasAllPropsvalidPeoplevalidDate 理想情况下都应该接收 req 并返回 null 或错误。然后你可以这样做:

    function validDate(req) {
      return null;
    }
    
    function validOtherProp(req) {
      return 'error_here';
    }
    
    function anotherValidation(req) {
      return 'second_error';
    }
    
    const errorCollectorMiddleware = (...validators) =>
      (req, res, next) => {
        const errors = validators.map(v => v(req)).filter(error => error !== null);
    
        if (errors.length > 0) {
          next({
            status: 400,
            errors
          })
        } else {
          next();
        }
      }
    
    // This is how you construct a middleware
    const middleware = errorCollectorMiddleware(validDate, validOtherProp, anotherValidation);
    
    // And here's a test. You wouldn't do this in your actual code.
    console.log(middleware(null, null, console.log))
    /*
    {
      "status": 400,
      "errors": [
        "error_here",
        "second_error"
      ]
    }
    */

    【讨论】:

      【解决方案2】:

      使用 HTTP/S,您不能有一个请求两个响应。客户端系统发送请求,接收响应并且不期望第二个响应。

      【讨论】:

        猜你喜欢
        • 2016-07-26
        • 2023-03-19
        • 2018-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-04
        • 1970-01-01
        • 2011-01-19
        相关资源
        最近更新 更多