Browse Source

Associating exceptions with field name in error lists ( cf. #89 )

Yann Weber 9 years ago
parent
commit
5c1e89f890
3 changed files with 26 additions and 22 deletions
  1. 18
    14
      leapi/lecrud.py
  2. 7
    7
      leapi/letype.py
  3. 1
    1
      leapi/test/test_letype.py

+ 18
- 14
leapi/lecrud.py View File

@@ -10,15 +10,19 @@ import re
10 10
 
11 11
 class LeApiErrors(Exception):
12 12
     ## @brief Instanciate a new exceptions handling multiple exceptions
13
-    # @param expt_l list : A list of data check Exception
13
+    # @param exptexptions dict : A list of data check Exception with concerned field (or stuff) as key
14 14
     def __init__(self, msg = "Unknow error", exceptions = None):
15 15
         self._msg = msg
16 16
         self._exceptions = list() if exceptions is None else exceptions
17 17
 
18 18
     def __str__(self):
19 19
         msg = self._msg
20
-        for expt in self._exceptions:
21
-            msg += " {expt_name}:{expt_msg}; ".format(expt_name=expt.__class__.__name__, expt_msg=str(expt))
20
+        for obj, expt in self._exceptions.items():
21
+            msg += "\n\t{expt_obj} : ({expt_name}) {expt_msg}; ".format(
22
+                    expt_obj = obj,
23
+                    expt_name=expt.__class__.__name__,
24
+                    expt_msg=str(expt)
25
+            )
22 26
         return msg
23 27
 
24 28
 
@@ -193,7 +197,7 @@ class _LeCrud(object):
193 197
     # @throw LeApiDataCheckError if errors reported during check
194 198
     @classmethod
195 199
     def check_datas_value(cls, datas, complete = False, allow_internal = True):
196
-        err_l = [] #Stores errors
200
+        err_l = dict() #Stores errors
197 201
         correct = [] #Valid fields name
198 202
         mandatory = [] #mandatory fields name
199 203
         for fname, ftt in cls.fieldtypes().items():
@@ -209,11 +213,11 @@ class _LeCrud(object):
209 213
         unknown = provided - correct
210 214
         for u_f in unknown:
211 215
             #here we can check if the field is unknown or rejected because it is internal
212
-            err_l.append(AttributeError("Unknown or unauthorized field '%s'"%u_f))
216
+            err_l[u_f] = AttributeError("Unknown or unauthorized field '%s'"%u_f)
213 217
         #searching missings fields
214 218
         missings = mandatory - provided
215 219
         for miss_field in missings:
216
-            err_l.append(AttributeError("The data for field '%s' is missing"%miss_field))
220
+            err_l[miss_field] = AttributeError("The data for field '%s' is missing"%miss_field)
217 221
         #Checks datas
218 222
         checked_datas = dict()
219 223
         for name, value in [ (name, value) for name, value in datas.items() if name in correct ]:
@@ -223,7 +227,7 @@ class _LeCrud(object):
223 227
             checked_datas[name], err = r
224 228
             #checked_datas[name], err = cls.fieldtypes()[name].check_data_value(value)
225 229
             if err:
226
-                err_l.append(err)
230
+                err_l[name] = err
227 231
 
228 232
         if len(err_l) > 0:
229 233
             raise LeApiDataCheckError("Error while checking datas", err_l)
@@ -323,10 +327,11 @@ class _LeCrud(object):
323 327
     @classmethod
324 328
     def _check_datas_consistency(cls, datas):
325 329
         err_l = []
330
+        err_l = dict()
326 331
         for fname, ftype in cls.fieldtypes().items():
327 332
             ret = ftype.check_data_consistency(cls, fname, datas)
328 333
             if isinstance(ret, Exception):
329
-                err_l.append(ret)
334
+                err_l[fname] = ret
330 335
 
331 336
         if len(err_l) > 0:
332 337
             raise LeApiDataCheckError("Datas consistency checks fails", err_l)
@@ -338,7 +343,7 @@ class _LeCrud(object):
338 343
     # @throw LeApiDataCheckError if invalid field given
339 344
     @classmethod
340 345
     def _prepare_field_list(cls, field_list):
341
-        err_l = list()
346
+        err_l = dict()
342 347
         ret_field_list = list()
343 348
         for field in field_list:
344 349
             if cls._field_is_relational(field):
@@ -347,7 +352,7 @@ class _LeCrud(object):
347 352
                 ret = cls._check_field(field)
348 353
 
349 354
             if isinstance(ret, Exception):
350
-                err_l.append(ret)
355
+                err_l[field] = ret
351 356
             else:
352 357
                 ret_field_list.append(ret)
353 358
 
@@ -366,7 +371,6 @@ class _LeCrud(object):
366 371
     # @return None if no problem, else returns a list of exceptions that occurs during the check
367 372
     @classmethod
368 373
     def _check_field(cls, field):
369
-        err_l = list()
370 374
         if field not in cls.fieldlist():
371 375
             return ValueError("No such field '%s' in %s"%(field, cls.__name__))
372 376
         return field
@@ -388,7 +392,7 @@ class _LeCrud(object):
388 392
         filters = list()
389 393
         res_filters = list()
390 394
         rel_filters = list()
391
-        err_l = list()
395
+        err_l = dict()
392 396
         #Splitting in tuple if necessary
393 397
         for fil in filters_l:
394 398
             if len(fil) == 3 and not isinstance(fil, str):
@@ -401,14 +405,14 @@ class _LeCrud(object):
401 405
                 #Checks relational fields
402 406
                 ret = cls._prepare_relational_field(field)
403 407
                 if isinstance(ret, Exception):
404
-                    err_l.append(ret)
408
+                    err_l[field] = ret
405 409
                 else:
406 410
                     rel_filters.append((ret, operator, value))
407 411
             else:
408 412
                 #Checks other fields
409 413
                 ret = cls._check_field(field)
410 414
                 if isinstance(ret, Exception):
411
-                    err_l.append(ret)
415
+                    err_l[field] = ret
412 416
                 else:
413 417
                     res_filters.append((field,operator, value))
414 418
 

+ 7
- 7
leapi/letype.py View File

@@ -47,16 +47,16 @@ class _LeType(_LeClass):
47 47
                 raise RuntimeError("Trying to instanciate a %s with a clas_id that is not correct"%self.__class__.__name__)
48 48
 
49 49
         ## Populate the object from the datas received in kwargs
50
-        err_l = list()
50
+        err_l = dict()
51 51
         for name, value in kwargs.items():
52 52
             if name not in self._fields:
53
-                raise AttributeError("No such field '%s' for %s"%(name, self.__class__.__name__))
54
-
55
-            cvalue, err =  self.fieldtypes()[name].check_data_value(value)
56
-            if isinstance(err, Exception):
57
-                err_l.append(err)
53
+                err_l[name] = AttributeError("No such field '%s' for %s"%(name, self.__class__.__name__))
58 54
             else:
59
-                setattr(self, name, value)
55
+                cvalue, err =  self.fieldtypes()[name].check_data_value(value)
56
+                if isinstance(err, Exception):
57
+                    err_l[name] = err
58
+                else:
59
+                    setattr(self, name, value)
60 60
         if len(err_l) > 0:
61 61
             raise LeApiDataCheckError("Invalid arguments given to constructor", err_l)
62 62
 

+ 1
- 1
leapi/test/test_letype.py View File

@@ -38,7 +38,7 @@ class LeTypeTestCase(TestCase):
38 38
 
39 39
         badargs = [
40 40
             ({'lodel_id':'foobar'}, TypeError),
41
-            ({'lodel_id': 42, 'titre_mais_qui_existe_pas':'hello'}, AttributeError),
41
+            ({'lodel_id': 42, 'titre_mais_qui_existe_pas':'hello'}, leapi.lecrud.LeApiDataCheckError),
42 42
         ]
43 43
         for badarg, expect_e in badargs:
44 44
             with self.assertRaises(expect_e, msg="Invalid argument given %s"%badarg):

Loading…
Cancel
Save