【问题标题】:joi: Custom errors are not returned, abortEarly is set to falsejoi:不返回自定义错误,abortEarly 设置为 false
【发布时间】:2017-04-05 04:41:56
【问题描述】:

我无法让这个 joi 验证返回所有错误,就像它对默认错误所做的那样。

所以我在这里为每个字段设置单独的自定义错误:

const schema = Joi.object().keys({
    a: Joi.string().error(new Error('must be string')), 
    b: Joi.number().error(new Error('must be number'))
});

然后当 abortEarly 设置为 false 进行验证时,它只返回将遇到的第一个错误。

Joi.validate({a: 1, b: false}, schema, {abortEarly: false})

返回的错误是这样的,

{ error: [Error: must be string], value: { a: 1, b: false }}

什么时候应该以某种方式返回所有错误。

我是在错误地使用 abortEarly,还是需要执行一个流程来返回所有自定义错误?提前感谢您的任何回复。

【问题讨论】:

    标签: javascript node.js hapijs joi


    【解决方案1】:

    嗯,我想我找到了答案。我的 joi 库没有更新,所以我将它从 10.2.x 升级到 10.4.1。我在文档中看到的一些功能在我在旧版本中尝试时不起作用,包括我所做的解决方案。

    我尝试使用这种模式并且它有效:

    const schema = Joi.object().keys({
        a: Joi.string().error(() => 'must be string'), 
        b: Joi.number().error(() => 'must be number')
    });
    

    像这样:

    { [ValidationError: child "a" fails because [must be string]. child "b" fails because [must be number]]
      isJoi: true,
      name: 'ValidationError',
      details: 
       [ { message: '"a" must be a string',
           path: 'a',
           type: 'string.base',
           context: [Object] },
         { message: '"b" must be a number',
           path: 'b',
           type: 'number.base',
           context: [Object] } ],
      _object: { a: 1, b: false },
      annotate: [Function] }
    

    然后我将解析error.message 以获取所有错误消息并进行处理。

    'child "a" fails because [must be string]. child "b" fails because [must be number]'
    

    【讨论】:

      【解决方案2】:

      我还有另一种方法来检查每个验证错误。 如果你有一个验证,不管条件是什么,你都可以这样做:

      username: Joi.string() // It has to be string
        .label("Username") // The label
        .error(new Error('It is whatever error')) // Custom general error
      

      你也可以用箭头功能做到这一点:

      username: Joi.string() // It has to be string
        .label("Username") // The label
        .error(() => 'It is whatever error') // Custom general error
      

      但如果有一些验证参数和错误,我们有这些解决方案:

      password: Joi.string()  // It has to be string
        .min(8) // It has to have at least 8 characters
        .required() // It has to have a value
        .label("Password") // The label
        .error(errors => {
          return errors.map(err => { // Here we map the errors (ES6) discover within an array
             if (err.type === "string.min") { // Check the type of error e.g: 'string.min,any.empty,number.min,...'
               return { message: "The length of the parameter should be more than 8 characters" }; // Which message we want to display
             } else {
               return { message: "another validation error" };
             }
          });
        })
      

      还有另一种使用 Switch Case 的解决方案:

      password: Joi.string()  // It has to be string
        .min(8) // It has to have at least 8 characters
        .required() // It has to have a value
        .label("Password") // The label
        .error(errors => {
          return errors.map(err => { // Here we map the errors (ES6) discover within an array
           switch (err.type) {
             case "string.min":
                return { message: "The length of the parameter should be more than 8 characters" }; // Which message we want to display
             case "any.empty":
                return { message: "The parameter should have a value" };
           }
        });
      })
      

      请注意,如果其中一个验证错误未指定您有 err.type 未定义的错误。

      您可以在消息中使用 err.context 以动态显示标签、限制、最大值、...:

      message: `${err.context.label} must have at least ${err.context.limit} characters.`
      

      参考:Joi Document

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-14
        • 1970-01-01
        • 2010-11-08
        • 2016-04-24
        • 2020-02-12
        • 1970-01-01
        • 2014-09-30
        • 2020-04-03
        相关资源
        最近更新 更多