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
« prev ^ index » next coverage.py v7.2.3, created at 2023-04-17 20:05 -0700
1"""
2Exceptions used in construction
3"""
5from typing import List, Optional
7from dj.errors import DJError, DJException
10class CompoundBuildException:
11 """
12 Exception singleton to optionally build up exceptions or raise
13 """
15 errors: List[DJError]
16 _instance: Optional["CompoundBuildException"] = None
17 _raise: bool = True
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
27 def reset(self):
28 """
29 Resets the singleton
30 """
31 self._raise = True
32 self.errors = []
34 def set_raise(self, raise_: bool):
35 """
36 Set whether to raise caught exceptions or accumulate them
37 """
38 self._raise = raise_
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)
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 )