1 |
3a515b92
|
cagy
|
# ajv-errors
|
2 |
|
|
Custom error messages in JSON-Schema for Ajv validator
|
3 |
|
|
|
4 |
|
|
[](https://travis-ci.org/epoberezkin/ajv-errors)
|
5 |
|
|
[](http://badge.fury.io/js/ajv-errors)
|
6 |
|
|
[](https://coveralls.io/github/epoberezkin/ajv-errors?branch=master)
|
7 |
|
|
[](https://gitter.im/ajv-validator/ajv)
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
## Contents
|
11 |
|
|
|
12 |
|
|
- [Install](#install)
|
13 |
|
|
- [Usage](#usage)
|
14 |
|
|
- [Single message](#single-message)
|
15 |
|
|
- [Messages for keywords](#messages-for-keywords)
|
16 |
|
|
- [Messages for properties and items](#messages-for-properties-and-items)
|
17 |
|
|
- [Default message](#default-message)
|
18 |
|
|
- [Templates](#templates)
|
19 |
|
|
- [Options](#options)
|
20 |
|
|
- [License](#license)
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
## Install
|
24 |
|
|
|
25 |
|
|
```
|
26 |
|
|
npm install ajv-errors
|
27 |
|
|
```
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
## Usage
|
31 |
|
|
|
32 |
|
|
Add the keyword `errorMessages` to Ajv instance:
|
33 |
|
|
|
34 |
|
|
```javascript
|
35 |
|
|
var Ajv = require('ajv');
|
36 |
|
|
var ajv = new Ajv({allErrors: true, jsonPointers: true});
|
37 |
|
|
// Ajv options allErrors and jsonPointers are required
|
38 |
|
|
require('ajv-errors')(ajv /*, {singleError: true} */);
|
39 |
|
|
```
|
40 |
|
|
|
41 |
|
|
See [Options](#options) below.
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
### Single message
|
45 |
|
|
|
46 |
|
|
Replace all errors in the current schema and subschemas with a single message:
|
47 |
|
|
|
48 |
|
|
```javascript
|
49 |
|
|
var schema = {
|
50 |
|
|
type: 'object',
|
51 |
|
|
required: ['foo'],
|
52 |
|
|
properties: {
|
53 |
|
|
foo: { type: 'integer' }
|
54 |
|
|
},
|
55 |
|
|
additionalProperties: false,
|
56 |
|
|
errorMessage: 'should be an object with an integer property foo only'
|
57 |
|
|
};
|
58 |
|
|
|
59 |
|
|
var validate = ajv.compile(schema);
|
60 |
|
|
console.log(validate({foo: 'a', bar: 2})); // false
|
61 |
|
|
console.log(validate.errors); // processed errors
|
62 |
|
|
```
|
63 |
|
|
|
64 |
|
|
Processed errors:
|
65 |
|
|
|
66 |
|
|
```javascript
|
67 |
|
|
[
|
68 |
|
|
{
|
69 |
|
|
keyword: 'errorMessage',
|
70 |
|
|
message: 'should be an object with an integer property foo only',
|
71 |
|
|
// ...
|
72 |
|
|
params: {
|
73 |
|
|
errors: [
|
74 |
|
|
{ keyword: 'additionalProperties', dataPath: '' /* , ... */ },
|
75 |
|
|
{ keyword: 'type', dataPath: '.foo' /* , ... */ }
|
76 |
|
|
]
|
77 |
|
|
}
|
78 |
|
|
}
|
79 |
|
|
]
|
80 |
|
|
```
|
81 |
|
|
|
82 |
|
|
|
83 |
|
|
### Messages for keywords
|
84 |
|
|
|
85 |
|
|
Replace errors for certain keywords in the current schema only:
|
86 |
|
|
|
87 |
|
|
```javascript
|
88 |
|
|
var schema = {
|
89 |
|
|
type: 'object',
|
90 |
|
|
required: ['foo'],
|
91 |
|
|
properties: {
|
92 |
|
|
foo: { type: 'integer' }
|
93 |
|
|
},
|
94 |
|
|
additionalProperties: false,
|
95 |
|
|
errorMessage: {
|
96 |
|
|
type: 'should be an object', // will not replace internal "type" error for the property "foo"
|
97 |
|
|
required: 'should have property foo',
|
98 |
|
|
additionalProperties: 'should not have properties other than foo'
|
99 |
|
|
}
|
100 |
|
|
};
|
101 |
|
|
|
102 |
|
|
var validate = ajv.compile(schema);
|
103 |
|
|
console.log(validate({foo: 'a', bar: 2})); // false
|
104 |
|
|
console.log(validate.errors); // processed errors
|
105 |
|
|
```
|
106 |
|
|
|
107 |
|
|
Processed errors:
|
108 |
|
|
|
109 |
|
|
```javascript
|
110 |
|
|
[
|
111 |
|
|
{
|
112 |
|
|
// original error
|
113 |
|
|
keyword: type,
|
114 |
|
|
dataPath: '/foo',
|
115 |
|
|
// ...
|
116 |
|
|
message: 'should be integer'
|
117 |
|
|
},
|
118 |
|
|
{
|
119 |
|
|
// generated error
|
120 |
|
|
keyword: 'errorMessage',
|
121 |
|
|
message: 'should not have properties other than foo',
|
122 |
|
|
// ...
|
123 |
|
|
params: {
|
124 |
|
|
errors: [
|
125 |
|
|
{ keyword: 'additionalProperties' /* , ... */ }
|
126 |
|
|
]
|
127 |
|
|
},
|
128 |
|
|
}
|
129 |
|
|
]
|
130 |
|
|
```
|
131 |
|
|
|
132 |
|
|
For keywords "required" and "dependencies" it is possible to specify different messages for different properties:
|
133 |
|
|
|
134 |
|
|
```javascript
|
135 |
|
|
var schema = {
|
136 |
|
|
type: 'object',
|
137 |
|
|
required: ['foo', 'bar'],
|
138 |
|
|
properties: {
|
139 |
|
|
foo: { type: 'integer' },
|
140 |
|
|
bar: { type: 'string' }
|
141 |
|
|
},
|
142 |
|
|
errorMessage: {
|
143 |
|
|
type: 'should be an object', // will not replace internal "type" error for the property "foo"
|
144 |
|
|
required: {
|
145 |
|
|
foo: 'should have an integer property "foo"',
|
146 |
|
|
bar: 'should have a string property "bar"'
|
147 |
|
|
}
|
148 |
|
|
}
|
149 |
|
|
};
|
150 |
|
|
```
|
151 |
|
|
|
152 |
|
|
|
153 |
|
|
### Messages for properties and items
|
154 |
|
|
|
155 |
|
|
Replace errors for properties / items (and deeper), regardless where in schema they were created:
|
156 |
|
|
|
157 |
|
|
```javascript
|
158 |
|
|
var schema = {
|
159 |
|
|
type: 'object',
|
160 |
|
|
required: ['foo', 'bar'],
|
161 |
|
|
allOf: [{
|
162 |
|
|
properties: {
|
163 |
|
|
foo: { type: 'integer', minimum: 2 },
|
164 |
|
|
bar: { type: 'string', minLength: 2 }
|
165 |
|
|
},
|
166 |
|
|
additionalProperties: false
|
167 |
|
|
}],
|
168 |
|
|
errorMessage: {
|
169 |
|
|
properties: {
|
170 |
|
|
foo: 'data.foo should be integer >= 2',
|
171 |
|
|
bar: 'data.bar should be string with length >= 2'
|
172 |
|
|
}
|
173 |
|
|
}
|
174 |
|
|
};
|
175 |
|
|
|
176 |
|
|
var validate = ajv.compile(schema);
|
177 |
|
|
console.log(validate({foo: 1, bar: 'a'})); // false
|
178 |
|
|
console.log(validate.errors); // processed errors
|
179 |
|
|
```
|
180 |
|
|
|
181 |
|
|
Processed errors:
|
182 |
|
|
|
183 |
|
|
```javascript
|
184 |
|
|
[
|
185 |
|
|
{
|
186 |
|
|
keyword: 'errorMessage',
|
187 |
|
|
message: 'data.foo should be integer >= 2',
|
188 |
|
|
dataPath: '/foo',
|
189 |
|
|
// ...
|
190 |
|
|
params: {
|
191 |
|
|
errors: [
|
192 |
|
|
{ keyword: 'minimum' /* , ... */ }
|
193 |
|
|
]
|
194 |
|
|
},
|
195 |
|
|
},
|
196 |
|
|
{
|
197 |
|
|
keyword: 'errorMessage',
|
198 |
|
|
message: 'data.bar should be string with length >= 2',
|
199 |
|
|
dataPath: '/bar',
|
200 |
|
|
// ...
|
201 |
|
|
params: {
|
202 |
|
|
errors: [
|
203 |
|
|
{ keyword: 'minLength' /* , ... */ }
|
204 |
|
|
]
|
205 |
|
|
},
|
206 |
|
|
}
|
207 |
|
|
]
|
208 |
|
|
```
|
209 |
|
|
|
210 |
|
|
|
211 |
|
|
### Default message
|
212 |
|
|
|
213 |
|
|
When the value of keyword `errorMessage` is an object you can specify a message that will be used if any error appears that is not specified by keywords/properties/items:
|
214 |
|
|
|
215 |
|
|
```javascript
|
216 |
|
|
var schema = {
|
217 |
|
|
type: 'object',
|
218 |
|
|
required: ['foo', 'bar'],
|
219 |
|
|
allOf: [{
|
220 |
|
|
properties: {
|
221 |
|
|
foo: { type: 'integer', minimum: 2 },
|
222 |
|
|
bar: { type: 'string', minLength: 2 }
|
223 |
|
|
},
|
224 |
|
|
additionalProperties: false
|
225 |
|
|
}],
|
226 |
|
|
errorMessage: {
|
227 |
|
|
type: 'data should be an object',
|
228 |
|
|
properties: {
|
229 |
|
|
foo: 'data.foo should be integer >= 2',
|
230 |
|
|
bar: 'data.bar should be string with length >= 2'
|
231 |
|
|
},
|
232 |
|
|
_: 'data should have properties "foo" and "bar" only'
|
233 |
|
|
}
|
234 |
|
|
};
|
235 |
|
|
|
236 |
|
|
var validate = ajv.compile(schema);
|
237 |
|
|
console.log(validate({})); // false
|
238 |
|
|
console.log(validate.errors); // processed errors
|
239 |
|
|
```
|
240 |
|
|
|
241 |
|
|
Processed errors:
|
242 |
|
|
|
243 |
|
|
```javascript
|
244 |
|
|
[
|
245 |
|
|
{
|
246 |
|
|
keyword: 'errorMessage',
|
247 |
|
|
message: 'data should be an object with properties "foo" and "bar" only',
|
248 |
|
|
dataPath: '',
|
249 |
|
|
// ...
|
250 |
|
|
params: {
|
251 |
|
|
errors: [
|
252 |
|
|
{ keyword: 'required' /* , ... */ },
|
253 |
|
|
{ keyword: 'required' /* , ... */ }
|
254 |
|
|
]
|
255 |
|
|
},
|
256 |
|
|
}
|
257 |
|
|
]
|
258 |
|
|
```
|
259 |
|
|
|
260 |
|
|
The message in property `_` of `errorMessage` replaces the same errors that would have been replaced if `errorMessage` were a string.
|
261 |
|
|
|
262 |
|
|
|
263 |
|
|
## Templates
|
264 |
|
|
|
265 |
|
|
Custom error messages used in `errorMessage` keyword can be templates using [JSON-pointers](https://tools.ietf.org/html/rfc6901) or [relative JSON-pointers](http://tools.ietf.org/html/draft-luff-relative-json-pointer-00) to data being validated, in which case the value will be interpolated. Also see [examples](https://gist.github.com/geraintluff/5911303) of relative JSON-pointers.
|
266 |
|
|
|
267 |
|
|
The syntax to interpolate a value is `${<pointer>}`.
|
268 |
|
|
|
269 |
|
|
The values used in messages will be JSON-stringified:
|
270 |
|
|
- to differentiate between `false` and `"false"`, etc.
|
271 |
|
|
- to support structured values.
|
272 |
|
|
|
273 |
|
|
Example:
|
274 |
|
|
|
275 |
|
|
```json
|
276 |
|
|
{
|
277 |
|
|
"type": "object",
|
278 |
|
|
"properties": {
|
279 |
|
|
"size": {
|
280 |
|
|
"type": "number",
|
281 |
|
|
"minimum": 4
|
282 |
|
|
}
|
283 |
|
|
},
|
284 |
|
|
"errorMessage": {
|
285 |
|
|
"properties": {
|
286 |
|
|
"size": "size should be a number bigger or equal to 4, current value is ${/size}"
|
287 |
|
|
}
|
288 |
|
|
}
|
289 |
|
|
}
|
290 |
|
|
```
|
291 |
|
|
|
292 |
|
|
|
293 |
|
|
## Options
|
294 |
|
|
|
295 |
|
|
Defaults:
|
296 |
|
|
|
297 |
|
|
```javascript
|
298 |
|
|
{
|
299 |
|
|
keepErrors: false,
|
300 |
|
|
singleError: false
|
301 |
|
|
}
|
302 |
|
|
```
|
303 |
|
|
|
304 |
|
|
- _keepErrors_: keep original errors. Default is to remove matched errors (they will still be available in `params.errors` property of generated error). If an error was matched and included in the error generated by `errorMessage` keyword it will have property `emUsed: true`.
|
305 |
|
|
- _singleError_: create one error for all keywords used in `errorMessage` keyword (error messages defined for properties and items are not merged because they have different dataPaths). Multiple error messages are concatenated. Option values:
|
306 |
|
|
- `false` (default): create multiple errors, one for each message
|
307 |
|
|
- `true`: create single error, messages are concatenated using `"; "`
|
308 |
|
|
- non-empty string: this string is used as a separator to concatenate messages
|
309 |
|
|
|
310 |
|
|
|
311 |
|
|
## Supporters
|
312 |
|
|
|
313 |
|
|
[<img src="https://media.licdn.com/mpr/mpr/shrinknp_400_400/AAEAAQAAAAAAAAwEAAAAJDg1YzBlYzFjLTA3YWYtNGEzOS1iMTdjLTQ0MTU1NWZjOGM0ZQ.jpg" width="48" height="48">](https://www.linkedin.com/in/rogerkepler/) [Roger Kepler](https://www.linkedin.com/in/rogerkepler/)
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
## License
|
317 |
|
|
|
318 |
|
|
[MIT](https://github.com/epoberezkin/ajv-errors/blob/master/LICENSE)
|