You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
7.9 KiB

4 years ago
  1. # ajv-errors
  2. Custom error messages in JSON-Schema for Ajv validator
  3. [![Build Status](https://travis-ci.org/epoberezkin/ajv-errors.svg?branch=master)](https://travis-ci.org/epoberezkin/ajv-errors)
  4. [![npm version](https://badge.fury.io/js/ajv-errors.svg)](http://badge.fury.io/js/ajv-errors)
  5. [![Coverage Status](https://coveralls.io/repos/github/epoberezkin/ajv-errors/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/ajv-errors?branch=master)
  6. [![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv)
  7. ## Contents
  8. - [Install](#install)
  9. - [Usage](#usage)
  10. - [Single message](#single-message)
  11. - [Messages for keywords](#messages-for-keywords)
  12. - [Messages for properties and items](#messages-for-properties-and-items)
  13. - [Default message](#default-message)
  14. - [Templates](#templates)
  15. - [Options](#options)
  16. - [License](#license)
  17. ## Install
  18. ```
  19. npm install ajv-errors
  20. ```
  21. ## Usage
  22. Add the keyword `errorMessages` to Ajv instance:
  23. ```javascript
  24. var Ajv = require('ajv');
  25. var ajv = new Ajv({allErrors: true, jsonPointers: true});
  26. // Ajv options allErrors and jsonPointers are required
  27. require('ajv-errors')(ajv /*, {singleError: true} */);
  28. ```
  29. See [Options](#options) below.
  30. ### Single message
  31. Replace all errors in the current schema and subschemas with a single message:
  32. ```javascript
  33. var schema = {
  34. type: 'object',
  35. required: ['foo'],
  36. properties: {
  37. foo: { type: 'integer' }
  38. },
  39. additionalProperties: false,
  40. errorMessage: 'should be an object with an integer property foo only'
  41. };
  42. var validate = ajv.compile(schema);
  43. console.log(validate({foo: 'a', bar: 2})); // false
  44. console.log(validate.errors); // processed errors
  45. ```
  46. Processed errors:
  47. ```javascript
  48. [
  49. {
  50. keyword: 'errorMessage',
  51. message: 'should be an object with an integer property foo only',
  52. // ...
  53. params: {
  54. errors: [
  55. { keyword: 'additionalProperties', dataPath: '' /* , ... */ },
  56. { keyword: 'type', dataPath: '.foo' /* , ... */ }
  57. ]
  58. }
  59. }
  60. ]
  61. ```
  62. ### Messages for keywords
  63. Replace errors for certain keywords in the current schema only:
  64. ```javascript
  65. var schema = {
  66. type: 'object',
  67. required: ['foo'],
  68. properties: {
  69. foo: { type: 'integer' }
  70. },
  71. additionalProperties: false,
  72. errorMessage: {
  73. type: 'should be an object', // will not replace internal "type" error for the property "foo"
  74. required: 'should have property foo',
  75. additionalProperties: 'should not have properties other than foo'
  76. }
  77. };
  78. var validate = ajv.compile(schema);
  79. console.log(validate({foo: 'a', bar: 2})); // false
  80. console.log(validate.errors); // processed errors
  81. ```
  82. Processed errors:
  83. ```javascript
  84. [
  85. {
  86. // original error
  87. keyword: type,
  88. dataPath: '/foo',
  89. // ...
  90. message: 'should be integer'
  91. },
  92. {
  93. // generated error
  94. keyword: 'errorMessage',
  95. message: 'should not have properties other than foo',
  96. // ...
  97. params: {
  98. errors: [
  99. { keyword: 'additionalProperties' /* , ... */ }
  100. ]
  101. },
  102. }
  103. ]
  104. ```
  105. For keywords "required" and "dependencies" it is possible to specify different messages for different properties:
  106. ```javascript
  107. var schema = {
  108. type: 'object',
  109. required: ['foo', 'bar'],
  110. properties: {
  111. foo: { type: 'integer' },
  112. bar: { type: 'string' }
  113. },
  114. errorMessage: {
  115. type: 'should be an object', // will not replace internal "type" error for the property "foo"
  116. required: {
  117. foo: 'should have an integer property "foo"',
  118. bar: 'should have a string property "bar"'
  119. }
  120. }
  121. };
  122. ```
  123. ### Messages for properties and items
  124. Replace errors for properties / items (and deeper), regardless where in schema they were created:
  125. ```javascript
  126. var schema = {
  127. type: 'object',
  128. required: ['foo', 'bar'],
  129. allOf: [{
  130. properties: {
  131. foo: { type: 'integer', minimum: 2 },
  132. bar: { type: 'string', minLength: 2 }
  133. },
  134. additionalProperties: false
  135. }],
  136. errorMessage: {
  137. properties: {
  138. foo: 'data.foo should be integer >= 2',
  139. bar: 'data.bar should be string with length >= 2'
  140. }
  141. }
  142. };
  143. var validate = ajv.compile(schema);
  144. console.log(validate({foo: 1, bar: 'a'})); // false
  145. console.log(validate.errors); // processed errors
  146. ```
  147. Processed errors:
  148. ```javascript
  149. [
  150. {
  151. keyword: 'errorMessage',
  152. message: 'data.foo should be integer >= 2',
  153. dataPath: '/foo',
  154. // ...
  155. params: {
  156. errors: [
  157. { keyword: 'minimum' /* , ... */ }
  158. ]
  159. },
  160. },
  161. {
  162. keyword: 'errorMessage',
  163. message: 'data.bar should be string with length >= 2',
  164. dataPath: '/bar',
  165. // ...
  166. params: {
  167. errors: [
  168. { keyword: 'minLength' /* , ... */ }
  169. ]
  170. },
  171. }
  172. ]
  173. ```
  174. ### Default message
  175. 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:
  176. ```javascript
  177. var schema = {
  178. type: 'object',
  179. required: ['foo', 'bar'],
  180. allOf: [{
  181. properties: {
  182. foo: { type: 'integer', minimum: 2 },
  183. bar: { type: 'string', minLength: 2 }
  184. },
  185. additionalProperties: false
  186. }],
  187. errorMessage: {
  188. type: 'data should be an object',
  189. properties: {
  190. foo: 'data.foo should be integer >= 2',
  191. bar: 'data.bar should be string with length >= 2'
  192. },
  193. _: 'data should have properties "foo" and "bar" only'
  194. }
  195. };
  196. var validate = ajv.compile(schema);
  197. console.log(validate({})); // false
  198. console.log(validate.errors); // processed errors
  199. ```
  200. Processed errors:
  201. ```javascript
  202. [
  203. {
  204. keyword: 'errorMessage',
  205. message: 'data should be an object with properties "foo" and "bar" only',
  206. dataPath: '',
  207. // ...
  208. params: {
  209. errors: [
  210. { keyword: 'required' /* , ... */ },
  211. { keyword: 'required' /* , ... */ }
  212. ]
  213. },
  214. }
  215. ]
  216. ```
  217. The message in property `_` of `errorMessage` replaces the same errors that would have been replaced if `errorMessage` were a string.
  218. ## Templates
  219. 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.
  220. The syntax to interpolate a value is `${<pointer>}`.
  221. The values used in messages will be JSON-stringified:
  222. - to differentiate between `false` and `"false"`, etc.
  223. - to support structured values.
  224. Example:
  225. ```json
  226. {
  227. "type": "object",
  228. "properties": {
  229. "size": {
  230. "type": "number",
  231. "minimum": 4
  232. }
  233. },
  234. "errorMessage": {
  235. "properties": {
  236. "size": "size should be a number bigger or equal to 4, current value is ${/size}"
  237. }
  238. }
  239. }
  240. ```
  241. ## Options
  242. Defaults:
  243. ```javascript
  244. {
  245. keepErrors: false,
  246. singleError: false
  247. }
  248. ```
  249. - _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`.
  250. - _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:
  251. - `false` (default): create multiple errors, one for each message
  252. - `true`: create single error, messages are concatenated using `"; "`
  253. - non-empty string: this string is used as a separator to concatenate messages
  254. ## Supporters
  255. [<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/)
  256. ## License
  257. [MIT](https://github.com/epoberezkin/ajv-errors/blob/master/LICENSE)