@@ -1958,8 +1958,9 @@ Diaspora.components = {
19581958 Set : require ( './set' ) ,
19591959 Model : require ( './model' ) ,
19601960 Errors : {
1961- ValidationError : require ( './errors/validationError' ) ,
1962- EntityStateError : require ( './errors/entityStateError' ) ,
1961+ EntityValidationError : require ( './errors/entityValidationError' ) ,
1962+ SetValidationError : require ( './errors/setValidationError' ) ,
1963+ EntityStateError : require ( './errors/entityStateError' ) ,
19631964 } ,
19641965 DiasporaAdapter : require ( './adapters/baseAdapter' ) ,
19651966 DataStoreEntity : require ( './dataStoreEntities/baseEntity' ) ,
@@ -1973,15 +1974,15 @@ if ( process.browser ) {
19731974}
19741975
19751976} ) . call ( this , require ( '_process' ) )
1976- } , { "./adapters/baseAdapter" :2 , "./adapters/browserStorageAdapter" :3 , "./adapters/inMemoryAdapter" :4 , "./dataStoreEntities/baseEntity" :5 , "./dependencies" :8 , "./entityFactory" :10 , "./errors/entityStateError" :11 , "./errors/validationError" : 13 , "./model " :14 , "./set " :15 , "_process" :17 , "winston" :undefined } ] , 10 :[ function ( require , module , exports ) {
1977+ } , { "./adapters/baseAdapter" :2 , "./adapters/browserStorageAdapter" :3 , "./adapters/inMemoryAdapter" :4 , "./dataStoreEntities/baseEntity" :5 , "./dependencies" :8 , "./entityFactory" :10 , "./errors/entityStateError" :11 , "./errors/entityValidationError" : 12 , "./errors/setValidationError " :14 , "./model " :15 , "./set" : 16 , " _process" :18 , "winston" :undefined } ] , 10 :[ function ( require , module , exports ) {
19771978'use strict' ;
19781979
19791980const {
19801981 _, Promise, SequentialEvent,
19811982} = require ( './dependencies' ) ;
19821983const Diaspora = require ( './diaspora' ) ;
19831984const DataStoreEntity = require ( './dataStoreEntities/baseEntity' ) ;
1984- const ValidationError = require ( './errors/validationError ' ) ;
1985+ const EntityValidationError = require ( './errors/entityValidationError ' ) ;
19851986const EntityStateError = require ( './errors/entityStateError' ) ;
19861987const Utils = require ( './utils' ) ;
19871988
@@ -2275,14 +2276,14 @@ function EntityFactory( name, modelDesc, model ) {
22752276 * @memberof EntityFactory.Entity
22762277 * @instance
22772278 * @author gerkin
2278- * @throws ValidationError Thrown if validation failed. This breaks event chain and prevent persistance.
2279+ * @throws EntityValidationError Thrown if validation failed. This breaks event chain and prevent persistance.
22792280 * @returns {undefined } This function does not return anything.
22802281 * @see Diaspora.check
22812282 */
22822283 validate ( ) {
22832284 const validationErrors = Diaspora . check ( attributes , modelDesc . attributes ) ;
22842285 if ( ! _ . isEmpty ( validationErrors ) ) {
2285- throw new ValidationError ( validationErrors , 'Validation failed' ) ;
2286+ throw new EntityValidationError ( validationErrors , 'Validation failed' ) ;
22862287 }
22872288 } ,
22882289 } ;
@@ -2471,7 +2472,7 @@ function EntityFactory( name, modelDesc, model ) {
24712472
24722473module . exports = EntityFactory ;
24732474
2474- } , { "./dataStoreEntities/baseEntity" :5 , "./dependencies" :8 , "./diaspora" :9 , "./errors/entityStateError" :11 , "./errors/validationError" : 13 , "./utils" :16 } ] , 11 :[ function ( require , module , exports ) {
2475+ } , { "./dataStoreEntities/baseEntity" :5 , "./dependencies" :8 , "./diaspora" :9 , "./errors/entityStateError" :11 , "./errors/entityValidationError" : 12 , "./utils" :17 } ] , 11 :[ function ( require , module , exports ) {
24752476'use strict' ;
24762477
24772478const ExtendableError = require ( './extendableError' ) ;
@@ -2495,7 +2496,49 @@ class EntityStateError extends ExtendableError {
24952496
24962497module . exports = EntityStateError ;
24972498
2498- } , { "./extendableError" :12 } ] , 12 :[ function ( require , module , exports ) {
2499+ } , { "./extendableError" :13 } ] , 12 :[ function ( require , module , exports ) {
2500+ 'use strict' ;
2501+
2502+ const {
2503+ _,
2504+ } = require ( '../dependencies' ) ;
2505+ const ExtendableError = require ( './extendableError' ) ;
2506+
2507+ const stringifyValidationObject = validationErrors => {
2508+ return _ ( validationErrors ) . mapValues ( ( error , key ) => {
2509+ return `${ key } => ${ JSON . stringify ( error . value ) }
2510+ * ${ _ ( error ) . omit ( [ 'value' ] ) . values ( ) . map ( _ . identity ) . value ( ) } ` ;
2511+ } ) . values ( ) . join ( '\n* ' ) ;
2512+ } ;
2513+
2514+ /**
2515+ * This class represents an error related to validation.
2516+ *
2517+ * @extends Error
2518+ * @memberof Errors
2519+ */
2520+ class EntityValidationError extends ExtendableError {
2521+ /**
2522+ * Construct a new validation error.
2523+ *
2524+ * @author gerkin
2525+ * @see Diaspora.check
2526+ * @memberof Errors
2527+ * @param {Object } validationErrors - Object describing validation errors, usually returned by {@link Diaspora.check}.
2528+ * @param {string } message - Message of this error.
2529+ * @param {* } errorArgs - Arguments to transfer to parent Error.
2530+ */
2531+ constructor ( validationErrors , message , ...errorArgs ) {
2532+ message += `
2533+ ${ stringifyValidationObject ( validationErrors ) } `;
2534+ super ( message , ...errorArgs ) ;
2535+ this . validationErrors = validationErrors ;
2536+ }
2537+ }
2538+
2539+ module . exports = EntityValidationError ;
2540+
2541+ } , { "../dependencies" :8 , "./extendableError" :13 } ] , 13 :[ function ( require , module , exports ) {
24992542'use strict' ;
25002543
25012544/**
@@ -2527,47 +2570,48 @@ class ExtendableError extends Error {
25272570
25282571module . exports = ExtendableError ;
25292572
2530- } , { } ] , 13 :[ function ( require , module , exports ) {
2573+ } , { } ] , 14 :[ function ( require , module , exports ) {
25312574'use strict' ;
25322575
25332576const {
25342577 _,
25352578} = require ( '../dependencies' ) ;
25362579const ExtendableError = require ( './extendableError' ) ;
25372580
2538- const stringifyValidationObject = validationErrors => {
2539- return _ ( validationErrors ) . mapValues ( ( error , key ) => {
2540- return `${ key } => ${ JSON . stringify ( error . value ) }
2541- * ${ _ ( error ) . omit ( [ 'value' ] ) . values ( ) . map ( _ . identity ) . value ( ) } ` ;
2542- } ) . values ( ) . join ( '\n* ' ) ;
2543- } ;
25442581
25452582/**
2546- * This class represents an error related to validation.
2583+ * This class represents an error related to validation on a set.
2584+ *
25472585 * @extends Error
2586+ * @memberof Errors
25482587 */
2549- class ValidationError extends ExtendableError {
2588+ class SetValidationError extends ExtendableError {
25502589 /**
25512590 * Construct a new validation error.
2552- *
2591+ *
25532592 * @author gerkin
25542593 * @see Diaspora.check
25552594 * @memberof Errors
2556- * @param {Object } validationErrors - Object describing validation errors, usually returned by {@link Diaspora.check}.
2557- * @param {string } message - Message of this error.
2558- * @param {* } errorArgs - Arguments to transfer to parent Error.
2559- */
2560- constructor ( validationErrors , message , ...errorArgs ) {
2561- message += `
2562- ${ stringifyValidationObject ( validationErrors ) } `;
2595+ * @param {string } message - Message of this error.
2596+ * @param {Errors.EntityValidationError[] } validationErrors - Array of validation errors.
2597+ * @param {* } errorArgs - Arguments to transfer to parent Error.
2598+ */
2599+ constructor ( message , validationErrors , ...errorArgs ) {
2600+ message += `[\n${ _ ( validationErrors ) . map ( ( error , index ) => {
2601+ if ( _ . isNil ( error ) ) {
2602+ return false ;
2603+ } else {
2604+ return `${ index } : ${ error . message . replace ( / \n / g, '\n ' ) } ` ;
2605+ }
2606+ } ) . filter ( _ . identity ) . join ( ',\n' ) } \n]`;
25632607 super ( message , ...errorArgs ) ;
25642608 this . validationErrors = validationErrors ;
25652609 }
25662610}
25672611
2568- module . exports = ValidationError ;
2612+ module . exports = SetValidationError ;
25692613
2570- } , { "../dependencies" :8 , "./extendableError" :12 } ] , 14 :[ function ( require , module , exports ) {
2614+ } , { "../dependencies" :8 , "./extendableError" :13 } ] , 15 :[ function ( require , module , exports ) {
25712615'use strict' ;
25722616
25732617const {
@@ -2860,21 +2904,22 @@ class Model {
28602904
28612905module . exports = Model ;
28622906
2863- } , { "./dependencies" :8 , "./diaspora" :9 , "./entityFactory" :10 , "./set" :15 } ] , 15 :[ function ( require , module , exports ) {
2907+ } , { "./dependencies" :8 , "./diaspora" :9 , "./entityFactory" :10 , "./set" :16 } ] , 16 :[ function ( require , module , exports ) {
28642908'use strict' ;
28652909
28662910const {
28672911 _, Promise,
28682912} = require ( './dependencies' ) ;
28692913const Utils = require ( './utils' ) ;
2914+ const SetValidationError = require ( './errors/setValidationError' ) ;
28702915
28712916/**
28722917 * Collections are used to manage multiple entities at the same time. You may try to use this class as an array.
28732918 */
28742919class Set {
28752920 /**
28762921 * Create a new set, managing provided `entities` that must be generated from provided `model`.
2877- *
2922+ *
28782923 * @param {Model } model - Model describing entities managed by this set.
28792924 * @param {Entity|Entity[] } entities - Entities to manage with this set. Arguments are flattened, so you can provide as many nested arrays as you want.
28802925 */
@@ -2887,7 +2932,7 @@ class Set {
28872932 const defined = Utils . defineEnumerableProperties ( this , {
28882933 /**
28892934 * List entities of this set.
2890- *
2935+ *
28912936 * @name entities
28922937 * @readonly
28932938 * @memberof Set
@@ -2898,7 +2943,7 @@ class Set {
28982943 entities : entities ,
28992944 /**
29002945 * Model that generated this set.
2901- *
2946+ *
29022947 * @name model
29032948 * @readonly
29042949 * @memberof Set
@@ -2909,7 +2954,7 @@ class Set {
29092954 model : model ,
29102955 /**
29112956 * Number of entities in this set.
2912- *
2957+ *
29132958 * @name length
29142959 * @readonly
29152960 * @memberof Set
@@ -2947,7 +2992,7 @@ class Set {
29472992
29482993 /**
29492994 * Check if all entities in the first argument are from the expected model.
2950- *
2995+ *
29512996 * @author gerkin
29522997 * @throws {TypeError } Thrown if one of the entity is not from provided `model`.
29532998 * @param {Entity[] } entities - Array of entities to check.
@@ -2964,7 +3009,7 @@ class Set {
29643009
29653010 /**
29663011 * Persist all entities of this collection.
2967- *
3012+ *
29683013 * @fires EntityFactory.Entity#beforeUpdate
29693014 * @fires EntityFactory.Entity#afterUpdate
29703015 * @author gerkin
@@ -2977,7 +3022,21 @@ class Set {
29773022 return Promise . all ( this . entities . map ( entity => entity . emit ( 'beforePersist' ) ) ) . then ( ( ) => {
29783023 return Promise . all ( this . entities . map ( entity => entity . emit ( 'beforeValidate' ) ) ) ;
29793024 } ) . then ( ( ) => {
2980- return this . entities . map ( entity => entity . validate ( ) ) ;
3025+ let errors = 0 ;
3026+ const validationResults = this . entities . map ( entity => {
3027+ try {
3028+ entity . validate ( ) ;
3029+ return undefined ;
3030+ } catch ( e ) {
3031+ errors ++ ;
3032+ return e ;
3033+ }
3034+ } ) . value ( ) ;
3035+ if ( errors > 0 ) {
3036+ return Promise . reject ( new SetValidationError ( `Set validation failed for ${ errors } elements (on ${ this . length } ): ` , validationResults ) ) ;
3037+ } else {
3038+ return Promise . resolve ( ) ;
3039+ }
29813040 } ) . then ( ( ) => {
29823041 return Promise . all ( this . entities . map ( entity => entity . emit ( 'afterValidate' ) ) ) ;
29833042 } ) . then ( ( ) => {
@@ -2995,7 +3054,7 @@ class Set {
29953054
29963055 /**
29973056 * Reload all entities of this collection.
2998- *
3057+ *
29993058 * @fires EntityFactory.Entity#beforeFind
30003059 * @fires EntityFactory.Entity#afterFind
30013060 * @author gerkin
@@ -3015,7 +3074,7 @@ class Set {
30153074
30163075 /**
30173076 * Destroy all entities from this collection.
3018- *
3077+ *
30193078 * @fires EntityFactory.Entity#beforeDelete
30203079 * @fires EntityFactory.Entity#afterDelete
30213080 * @author gerkin
@@ -3035,7 +3094,7 @@ class Set {
30353094
30363095 /**
30373096 * Update all entities in the set with given object.
3038- *
3097+ *
30393098 * @author gerkin
30403099 * @param {Object } newData - Attributes to change in each entity of the collection.
30413100 * @returns {Collection } `this`.
@@ -3056,7 +3115,7 @@ class Set {
30563115
30573116module . exports = Set ;
30583117
3059- } , { "./dependencies" :8 , "./utils" :16 } ] , 16 :[ function ( require , module , exports ) {
3118+ } , { "./dependencies" :8 , "./errors/setValidationError" : 14 , "./ utils" :17 } ] , 17 :[ function ( require , module , exports ) {
30603119'use strict' ;
30613120
30623121const {
@@ -3084,7 +3143,7 @@ module.exports = {
30843143 } ,
30853144} ;
30863145
3087- } , { "./dependencies" :8 } ] , 17 :[ function ( require , module , exports ) {
3146+ } , { "./dependencies" :8 } ] , 18 :[ function ( require , module , exports ) {
30883147// shim for using process in browser
30893148var process = module . exports = { } ;
30903149
0 commit comments