【问题标题】:AJV JsonSchema validator reports seemingly incorrect errorAJV JsonSchema 验证器报告看似不正确的错误
【发布时间】:2021-11-26 22:19:01
【问题描述】:

我正在使用 AJV 针对架构验证 HTTP 请求负载。但是,我看到一个我没有预料到的错误报告。这是一个演示问题的代码示例:

const schema = {
  type: 'array',
  minItems: 1,
  items: {
    anyOf: [
      {
        type: 'object',
        properties: {
          op: {
            enum: ['replace']
          },
          path: {
            type: 'string',
            pattern: '/data/to/foo/bar',
          },
          value: {
            type: 'string',
          },
        },
      },{
        type: 'object',
        properties: {
          op: {
            enum: ['replace']
          },
          path: {
            type: 'string',
            pattern: '/data/to/baz',
          },
          value: {
            type: 'object',
            required: ['foo', 'bar'],
            properties: {
              foo: {
                type: 'string',
              },
              bar: {
                type: 'string',
              },
            }
          }
        }
      }
    ],
  },
}

const validator = new ajv()

const compiledValidator = validator.compile(schema)
  const data = [
  { // this object should pass
    op: 'replace',
    path: '/data/to/foo/bar',
    value: 'foo',
  },
  { // this object should fail in the `value` mismatch (missing required attribute)
    op: 'replace',
    path: '/data/to/baz',
    value: {
      foo: 'bar',
    },
  },
]

compiledValidator(data)

console.log(compiledValidator.errors)

模式定义了传入的数据对象列表应匹配的许多对象。第一个数据项与架构(第一项架构)匹配,但是第二个数据项缺少value 对象中的必需属性(bar)。

当我运行上面的代码时,我得到以下输出:

[
  {
    instancePath: '/1/path',
    schemaPath: '#/items/anyOf/0/properties/path/pattern',
    keyword: 'pattern',
    params: { pattern: '/data/to/foo/bar' },
    message: 'must match pattern "/data/to/foo/bar"'
  },
  {
    instancePath: '/1/value',
    schemaPath: '#/items/anyOf/1/properties/value/required',
    keyword: 'required',
    params: { missingProperty: 'bar' },
    message: "must have required property 'bar'"
  },
  {
    instancePath: '/1',
    schemaPath: '#/items/anyOf',
    keyword: 'anyOf',
    params: {},
    message: 'must match a schema in anyOf'
  }
]

我了解第二个和第三个(最后一个)错误。但是,第一个错误似乎表明 path 与第一项架构的 path 要求不匹配。确实,第二个数据项与第一个模式项不匹配,但我似乎不明白它是如何相关的。我假设错误将集中在value,而不是path,因为它与path 模式匹配。

有没有办法让错误报告更加关注重要的错误?

【问题讨论】:

  • 我认为它确实很重要。它显示了为什么第二个实例项与第一个 anyOf 选项不匹配。如果没有此错误,您可能会认为它与该选项匹配,在这种情况下,您会对最后一个错误感到困惑。
  • 嗯,是的,这让我感到困惑,因为第二个数据项的 path 与第二个模式项匹配。那么,为什么会报错……就匹配而言,两个数据项的path都没有问题。

标签: node.js jsonschema ajv


【解决方案1】:

评估者无法知道您是打算匹配第一个“anyOf”子模式还是第二个,因此最有用的做法是向您显示所有错误。

这可能会令人困惑,因为您不需要解决所有错误,只需解决其中的一些错误,这就是为什么some implementations also offer a heirarchical error format 可以更轻松地查看此类关系。也许如果您要求ajv 实现更多这些错误格式,它就会发生:)

【讨论】:

    【解决方案2】:

    通过查看每个错误的instancePath,您可以看到所有错误都与数据中的第二项有关,这些错误都以/1 开头。这是产生错误的数据中的位置

    让我们看一下第二项并将其与架构进行比较。

    { // this object should fail in the `value` mismatch (missing required attribute)
      op: 'replace',
      path: '/data/to/baz',
      value: {
        foo: 'bar',
      },
    }
    

    架构表明项目应该(来自anyOf)具有

    • path: '/data/to/foo/bar'value: { type: 'string' },或
    • path: '/data/to/baz'value: { required: [ 'foo', 'bar' ] }

    报告的错误是:

    1. 第一种情况失败,因为path 错误。
    2. 第二种情况失败,因为/value/bar 不存在。
    3. 最后一个错误只是 anyOf 报告没有通过任何选项。

    【讨论】:

      猜你喜欢
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多