类型的 Ajv 自定义错误消息

Posted

技术标签:

【中文标题】类型的 Ajv 自定义错误消息【英文标题】:Ajv custom error message for type 【发布时间】:2018-08-19 03:26:59 【问题描述】:

我正在使用 ajv-errors 探索 Ajv,以验证 json 架构并生成自定义错误消息。到目前为止一切正常,但我无法为单个值的类型设置自定义错误消息。

const emailSchema = 
 type: 'object',
 required: ['foo', 'bar', 'car'],
 properties: 
  foo:  type: 'integer' ,
  bar:  type: 'string' ,
  car:  type: 'string' 
 ,
 errorMessage: 
  type: 'should be an object',
  required: 
  foo: 'foo field is missing',
  bar: 'bar field is missing',
  car: 'car field is missing'
  
  
;

输出以下错误

[
    
        "keyword": "type",
        "dataPath": "/foo",
        "schemaPath": "#/properties/foo/type",
        "params": 
            "type": "integer"
        ,
        "message": "should be integer"
    ,
    
        "keyword": "errorMessage",
        "dataPath": "",
        "schemaPath": "#/errorMessage",
        "params": 
            "errors": [
                
                    "keyword": "required",
                    "dataPath": "",
                    "schemaPath": "#/required",
                    "params": 
                        "missingProperty": "bar"
                    ,
                    "message": "should have required property 'bar'"
                
            ]
        ,
        "message": "bar field is missing"
    ,
    
        "keyword": "errorMessage",
        "dataPath": "",
        "schemaPath": "#/errorMessage",
        "params": 
            "errors": [
                
                    "keyword": "required",
                    "dataPath": "",
                    "schemaPath": "#/required",
                    "params": 
                        "missingProperty": "car"
                    ,
                    "message": "should have required property 'car'"
                
            ]
        ,
        "message": "car field is missing"
    
]

第一个带有消息“应该是整数”的错误对象,我可以像 foo 一样自定义它必须是一个整数。 我期待像下面这样的东西,但它给出了架构错误。

type : 
  foo : "foo must be an Integer"

谢谢。

【问题讨论】:

【参考方案1】:

对于我们有一些自定义错误消息或任何其他数据的用例,我们必须使用模式路径。 当我们收到验证错误时,我们还会收到 error.keyword 在我的情况下,我在 if 和 else 块中进行了额外的验证,如下所示

schema.allOf= Object.keys(bankCodes).map((key: any) => (
    if: 
      properties: 
        routingCodeType1:  const: bankCodes[key].code ,
      ,
    ,
    then: 
      properties: 
        routingCodeValue1: 
          pattern: bankCodes[key].pattern, //<-- this was cause of validation fail
          errorMessage: bankCodes[key].errorMessage,
        ,
      ,
    ,
  ))

所以在error.keyword 我会得到pattern 以及schemaPath=/#/allOf/2/then/properties/routingCodeValue1/pattern

所以基本上我必须使用这个模式路径从模式中获取相关数据。以下代码帮助了我

const getPatternMessage = (error: any, schema: any) => 
  if (error.keyword === 'pattern') 
    const fieldName = error.dataPath.substring(1); // routingCodeValue1
    const keyArr = error.schemaPath.split('/'); // ['#','allOf','2'..,'pattern']
    keyArr.pop(); // remove '#'
    keyArr.shift(); // remove 'pattern'
    const prop = keyArr.reduce((acc, key) => acc[key], schema);
/** 
prop contains  
          pattern: '^[a-z]9$',
          errorMessage:'routingCodeValue1 should be 9 characters'
        ,
*/
    return 
      [fieldName]: prop.errorMessage,
    ;
  
;

通过这种方式,我们能够提取自定义错误消息或我们想要的任何其他数据

要点是使用 schemaPath 属性

【讨论】:

【参考方案2】:

您必须在每个属性中将errorMessage 声明为关键字,请参见此示例:

const emailSchema = 
  type: 'object',
  required: ['foo', 'bar', 'car'],
  properties: 
    foo: 
      type: 'integer',
      errorMessage: 
        // In here must be errorMessage not errorMessages
        type: 'foo must be an Integer', // Your Custom Error Message
      ,
    ,
    bar:  type: 'string' ,
    car:  type: 'string' ,
  ,
  errorMessages: 
    // Change from errorMessage to errorMessages
    type: 'should be an object',
    required: 
      foo: 'foo field is missing',
      bar: 'bar field is missing',
      car: 'car field is missing',
    ,
  ,


【讨论】:

以上是关于类型的 Ajv 自定义错误消息的主要内容,如果未能解决你的问题,请参考以下文章

最新的 AJV 和 ajv-formats 必须在 React 中被打破

Spring MVC 和 Thymeleaf 自定义错误消息类型转换

如何自定义有关“failureRequiringAppLaunch”类型的 Siri 意图响应的错误消息

如何在自定义 AuthenticationFailureHandler 中返回由具体派生 AuthenticationException 类型解析的不同错误消息

自定义 SignalR 的错误消息

在Swift 2中使用自定义消息抛出错误/异常的最简单方法?