简体   繁体   English

Joi 验证器替代模式错误消息

[英]Joi validator alternative schema error message

I as trying to create a Joi schema using Joi.alternatives.try() .我试图使用Joi.alternatives.try()创建一个 Joi 模式。 This is the schema I have tried.这是我尝试过的架构。

Joi.alternatives().try(Joi.object({
    type: Joi.number().required().label('Error1!!')
}), Joi.object({
    reason: Joi.string().required().label('Error2!!')
})).label('Error!!')

This is the object that I have used.这是我用过的object。

{ reason: 2 }

I was expecting the error as Error2!!我期待错误为Error2!! or something containing this the string Error2!!或包含此字符串Error2!! . . But im getting error as但我得到错误

Validation Error: "Error!!" does not match any of the allowed types

This error comes from the parent node.此错误来自父节点。

How can I make the error specific to the object?如何使错误特定于 object? i,e, an error that comes from the alternative object node rather that the parent object.即,来自备用 object 节点而不是父 object 节点的错误。

You can use this platform to validate schema online.您可以使用平台在线验证架构。

Update: Here is the sample schema that I used.更新:这是我使用的示例模式。

employee_retired = Joi.object({
    type: Joi.number().required().valid(2, 3, 7),
    reason: Joi.string().required()
        .min(1)
        .max(100),
    firstname: Joi.string()
        .required(),
    lastname: Joi.string()
        .required()
        .min(1)
        .max(255),
    personaldetails: Joi.alternatives().conditional('type', {
        is: 2, then: Joi.array().items(Joi.object({
            address: Joi.string().required()
                .min(1)
                .max(100),
            salary: Joi.string().required()
                .min(0)
                .max(500),
            contactnumbers: Joi.array().items(Joi.object({
                mobile: Joi.string().required()
                    .min(0)
                    .max(15),
                home: Joi.string()
                    .required()
                    .min(1)
                    .max(15),
            })).max(50).required(),
        }).required()).max(50).required(),
        otherwise: Joi.forbidden(),
    }),
    monthlysavings: Joi.alternatives().conditional('type', {
            is: 3,
            then: Joi.number()
                .required()
                .min(0)
                .max(50000),
            otherwise: Joi.forbidden(),
        }),
    isapproved: Joi.boolean().required(),
});

empolyee_working = Joi.object({
    type: Joi.number().required().valid(2, 3, 7),
    reason: Joi.string().required()
        .min(1)
        .max(100),
    firstname: Joi.string()
        .required(),
    lastname: Joi.string()
        .required()
        .min(1)
        .max(255),
    contactnumbers: Joi.array().items(Joi.object({
        mobile: Joi.string().required()
            .min(0)
            .max(15),
        home: Joi.string()
            .required()
            .min(1)
            .max(15),
    })).max(50).required(),
    monthlysavings: Joi.alternatives().conditional('type', {
        is: 3,
        then: Joi.number().required()
            .min(1)
            .max(50000),
        otherwise: Joi.forbidden(),
    }),
    isapproved: Joi.boolean().required(),
})

const employee = Joi.alternatives().try(employee_retired, empolyee_working);

You may useobject.or for this behavior:您可以使用object.or进行此行为:

Joi.object({
    type: Joi.number().label('Error1!!'),
    reason: Joi.string().label('Error2!!')
}).or('type', 'reason').label('Error!!')

Tests:测试:

{}
// Validation Error: "Error!!" must contain at least one of [Error1!!, Error2!!]
{ reason: 2 }
// Validation Error: "Error2!!" must be a string
{ type: "a" } // note that due to default `convert` behavior, `{ type: "2" }` would pass
// Validation Error: "Error1!!" must be a number
{ a: "b" }
// Validation Error: "a" is not allowed. "Error!!" must contain at least one of [Error1!!, Error2!!]

UPDATE (after comment)更新(评论后)

Indeed it's a bit more verbose, but follows the same logic:确实它有点冗长,但遵循相同的逻辑:

  • both retired and working employees share the same structure退休员工和在职员工共享相同的结构
  • only personaldetails and contactnumbers vary只有personaldetails详细信息和contactnumbers有所不同

So something along the following lines should provide you with a precise validation error message (I haven't tested all cases though).因此,以下内容应该为您提供精确的验证错误消息(尽管我还没有测试所有情况)。 I just "merged" both employee declarations, and the two varying cases personaldetails and contactnumbers are not declared required anymore but are specified in the final or .我只是“合并”了两个员工声明,两个不同的案例personaldetailscontactnumbers不再声明为required ,而是在最终的or中指定。

Joi.object({
    type: Joi.number().required().valid(2, 3, 7),
    reason: Joi.string().required()
        .min(1)
        .max(100),
    firstname: Joi.string()
        .required(),
    lastname: Joi.string()
        .required()
        .min(1)
        .max(255),
    personaldetails: Joi.alternatives().conditional('type', {
        is: 2, then: Joi.array().items(Joi.object({
            address: Joi.string().required()
                .min(1)
                .max(100),
            salary: Joi.string().required()
                .min(0)
                .max(500),
            contactnumbers: Joi.array().items(Joi.object({
                mobile: Joi.string().required()
                    .min(0)
                    .max(15),
                home: Joi.string()
                    .required()
                    .min(1)
                    .max(15),
            })).max(50).required(),
        // N.B.: no more .required() on the next line, .or() will handle it conditionally
        }).required()).max(50),
        otherwise: Joi.forbidden(),
    }),
    contactnumbers: Joi.array().items(Joi.object({
        mobile: Joi.string().required()
            .min(0)
            .max(15),
        home: Joi.string()
            .required()
            .min(1)
            .max(15),
    // N.B.: no more .required() on the next line, .or() will handle it conditionally
    })).max(50),
    monthlysavings: Joi.alternatives().conditional('type', {
            is: 3,
            then: Joi.number()
                .required()
                .min(0)
                .max(50000),
            otherwise: Joi.forbidden(),
        }),
    isapproved: Joi.boolean().required(),
}).or('personaldetails', 'contactnumbers').label('OR failure')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM