【问题标题】:How to get property name from ajv output to map validation errors to human friendly messages?如何从 ajv 输出中获取属性名称以将验证错误映射到人类友好的消息?
【发布时间】:2021-07-19 13:50:12
【问题描述】:

我正在使用 AJV 库 https://github.com/ajv-validator/ajv 来验证我的 nodejs express api 的输入。但是,我无法为返回的数组中的每个错误对象提取有问题的属性名称。

[{
  instancePath: '',
  schemaPath: '#/required',
  keyword: 'required',
  params: { missingProperty: 'start_date' },
  message: "must have required property 'start_date'"
}
{
  instancePath: '/top',
  schemaPath: '#/properties/top/type',
  keyword: 'type',
  params: { type: 'number' },
  message: 'must be number'
}]

从上面的输出中可以看出,为每个提取属性名称(start_date, top)有点不同,所以我希望有一种简单的方法可以做到这一点,而不必根据错误类型(关键字)进行解析.

期待

我希望能够创建如下映射原始数组的错误。为此,我需要上述原始输出中可用的消息和不可用的属性名称。

[
  {  property: "start_date", message: "must have required property 'start_date"}
  {  property: "top", message: "must be number" },
]

代码

export interface ILeaderboardQuery {
    rank: string;
    entity_types: string[];
    country?: string | undefined;
    region?: string | undefined;
    start_date: string;
    end_date: string;
    top?: number | undefined;
}

export const LeaderboardQuerySchema: JSONSchemaType<ILeaderboardQuery> = {
    type: "object",
    properties: {
        rank: { type: "string" },
        entity_types: {
            type: "array",
            items: {
                type: "string",
            },
        },
        country: { type: "string", nullable: true },
        region: { type: "string", nullable: true },
        start_date: { type: "string" },
        end_date: { type: "string" },
        top: { type: "number", nullable: true },
    },
    required: ["rank", "start_date", "end_date"],
    additionalProperties: false,
};

const ajv = new Ajv({ allErrors: true });

export const GetLeaderboardValidator = (req: Request, res: Response, next: NextFunction) => {
    const validate = ajv.compile<ILeaderboardQuery>(LeaderboardQuerySchema);

    for (const err of validate.errors as DefinedError[]) {
        console.log(err);
    }
};

ajv^8.6.2"

【问题讨论】:

    标签: javascript node.js ajv


    【解决方案1】:

    如果您不介意在架构中添加额外的非 JSON 架构术语,可以使用 ajv-errors 包。

    您可以将额外的errorMessage 添加到任何架构。它可以设置为字符串或对象。如果设置为对象,则其键设置为规则,值设置为错误消息。

    希望这是有道理的:

    const Ajv = require('ajv');
    const ajvErrors = require('ajv-errors');
    
    const ajv = new Ajv({allErrors: true});
    ajvErrors(ajv);
    
    const validate = ajv.compile({
      type: "object",
      required: ["foo"],
      additionalProperties: false,
      properties: {
        foo: {
          type: "number",
          errorMessage: "CUSTOM ERROR: foo must be a number"
        }
      },
      errorMessage: {
        type: "CUSTOM ERROR: not an object",
        required: "CUSTOM ERROR: missing required property foo",
        additionalProperties: "CUSTOM ERROR: cannot have other properties"
      }
    });
    
    
    validate("foo");
    validate.errors;
    
    /*
    [
      {
        instancePath: '',
        schemaPath: '#/errorMessage',
        keyword: 'errorMessage',
        params: { errors: [Array] },
        message: 'CUSTOM ERROR: not an object'
      }
    ]
    */
    
    validate({});
    validate.errors;
    
    /*
    [
      {
        instancePath: '',
        schemaPath: '#/errorMessage',
        keyword: 'errorMessage',
        params: { errors: [Array] },
        message: 'CUSTOM ERROR: missing required property foo'
      }
    ]
    */
    
    validate({foo: 1, bar: 2});
    validate.errors;
    
    /*
    [
      {
        instancePath: '',
        schemaPath: '#/errorMessage',
        keyword: 'errorMessage',
        params: { errors: [Array] },
        message: 'CUSTOM ERROR: cannot have other properties'
      }
    ]
    */
    
    validate({foo: "wat"});
    validate.errors;
    
    /*
    [
      {
        instancePath: '/foo',
        schemaPath: '#/properties/foo/errorMessage',
        keyword: 'errorMessage',
        params: { errors: [Array] },
        message: 'CUSTOM ERROR: foo must be a number'
      }
    ]
    */
    

    【讨论】:

    • 这个库似乎没有为我提供一种分隔属性名称的方法,至少在您展示的任何示例中我都看不到
    • 您可以在每个模式中添加一个错误消息并在那里自定义它们。只要在路径上失败,属性名称就在schemaPath 中。
    • 是的,所以这种方式回到了我试图避免根据keyword / 错误类型解析字符串的最初观点。我不需要这个扩展的功能,因为我真正想要的只是分隔属性名称,听起来使用这个扩展我仍然需要进行解析。
    猜你喜欢
    • 2020-07-28
    • 2016-05-15
    • 2020-07-15
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2012-10-08
    相关资源
    最近更新 更多