我使用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
模式匹配。
有没有办法让错误报告更加关注重要的错误?
评估者无法知道您是否打算进行第一次"任意";要匹配的子模式或第二个,所以最有用的做法是向您显示所有错误。
这可能会令人困惑,因为您不需要解决所有错误,只需要解决其中的一些错误,这就是为什么有些实现还提供了继承错误格式,使其更容易看到这样的关系。如果您请求ajv
实现更多的这些错误格式,可能会发生以下情况:(
通过查看每个错误的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' ] }
报告的错误为:
- 由于
path
错误,第一种情况失败 - 第二种情况失败,因为
/value/bar
不存在 - 最后一个错误只是
anyOf
报告没有通过任何选项