Coverage for dj/construction/exceptions.py: 100%

24 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-04-17 20:05 -0700

1""" 

2Exceptions used in construction 

3""" 

4 

5from typing import List, Optional 

6 

7from dj.errors import DJError, DJException 

8 

9 

10class CompoundBuildException: 

11 """ 

12 Exception singleton to optionally build up exceptions or raise 

13 """ 

14 

15 errors: List[DJError] 

16 _instance: Optional["CompoundBuildException"] = None 

17 _raise: bool = True 

18 

19 def __new__(cls, *args, **kwargs): 

20 if not cls._instance: 

21 cls._instance = super(CompoundBuildException, cls).__new__( 

22 cls, *args, **kwargs 

23 ) 

24 cls.errors = [] 

25 return cls._instance 

26 

27 def reset(self): 

28 """ 

29 Resets the singleton 

30 """ 

31 self._raise = True 

32 self.errors = [] 

33 

34 def set_raise(self, raise_: bool): 

35 """ 

36 Set whether to raise caught exceptions or accumulate them 

37 """ 

38 self._raise = raise_ 

39 

40 def append(self, error: DJError, message: Optional[str] = None): 

41 """ 

42 Accumulate DJ exceptions 

43 """ 

44 if self._raise: 

45 raise DJException( 

46 message=message or error.message, 

47 errors=[error], 

48 ) 

49 self.errors.append(error) 

50 

51 def __str__(self) -> str: 

52 plural = "s" if len(self.errors) > 1 else "" 

53 error = f"Found {len(self.errors)} issue{plural}:\n" 

54 return error + "\n\n".join( 

55 "\t" + str(type(exc).__name__) + ": " + str(exc) + "\n" + "=" * 50 

56 for exc in self.errors 

57 )