i was exploring Ajv with ajv-errors for validating json schema and producing custom error messages. everything works as of now but i can't set custom error message for type for individual values.
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'
}
}
};
outputs following error
[
{
"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"
}
]
the first error object with message "should be integer", can i customize it like foo must be an Integer. I am expecting something like below but it gives be schema error.
type : {
foo : "foo must be an Integer"
}
Thanks.
i was exploring Ajv with ajv-errors for validating json schema and producing custom error messages. everything works as of now but i can't set custom error message for type for individual values.
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'
}
}
};
outputs following error
[
{
"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"
}
]
the first error object with message "should be integer", can i customize it like foo must be an Integer. I am expecting something like below but it gives be schema error.
type : {
foo : "foo must be an Integer"
}
Thanks.
Share Improve this question asked Mar 10, 2018 at 18:41 Nikhil PujariNikhil Pujari 1631 gold badge2 silver badges14 bronze badges2 Answers
Reset to default 18You must declare errorMessage
as keyword inside each of properties, see this example:
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',
},
},
}
For use cases where we have some custom errorMessage or any other data, we have to use the schema path.
When we get the validation error, we also get the error.keyword
in my case I had extra validation in if and else block as below
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,
},
},
},
}))
so in the error.keyword
I would get pattern
as well as schemaPath=/#/allOf/2/then/properties/routingCodeValue1/pattern
so basically I would have to use this schema path to fetch the related data back from schema. Following code helped me with it
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,
};
}
};
This way we are able to extract get custom errorMessage or any other data we want
Gist is to use the schemaPath property