'Ajv custom error message for type
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.
Solution 1:[1]
You 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',
},
},
}
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Akshay Vijay Jain |
