Coverage for src / mafw / mafw_errors.py: 97%

72 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-05-12 09:03 +0000

1# Copyright 2025–2026 European Union 

2# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu) 

3# SPDX-License-Identifier: EUPL-1.2 

4""" 

5Module defines MAFw exceptions 

6""" 

7 

8 

9class MAFwException(Exception): 

10 """Base class for MAFwException""" 

11 

12 pass 

13 

14 

15class ProcessorParameterError(MAFwException): 

16 """Error with a processor parameter""" 

17 

18 pass 

19 

20 

21class InvalidConfigurationError(MAFwException): 

22 """Error with the configuration of a processor""" 

23 

24 pass 

25 

26 

27class MissingOverloadedMethod(UserWarning): 

28 """ 

29 Warning issued when the user did not overload a required method. 

30 

31 It is a warning and not an error because the execution framework might still work, but the results might be 

32 different from what is expected. 

33 """ 

34 

35 pass 

36 

37 

38class MissingSuperCall(UserWarning): 

39 """ 

40 Warning issued when the user did not invoke the super method for some specific processor methods. 

41 

42 Those methods (like :meth:`~mafw.processor.Processor.start` and :meth:`~mafw.processor.Processor.finish`) have not 

43 empty implementation also in the base class, meaning that if the user forgets to call *super* in their overloads, 

44 then the basic implementation will be gone. 

45 

46 It is a warning and not an error because the execution framework might sill work, but the results might be 

47 different from what is expected. 

48 """ 

49 

50 pass 

51 

52 

53class SteeringFileDeprecation(UserWarning): 

54 """ 

55 Warning issued when a legacy deprecated configuration is used in the steering file. 

56 

57 It is a warning and not an error because the execution framework might still work, but the configuration 

58 may be removed in future versions. 

59 """ 

60 

61 pass 

62 

63 

64class AbortProcessorException(MAFwException): 

65 """Exception raised during the execution of a processor requiring immediate exit.""" 

66 

67 pass 

68 

69 

70class RunnerNotInitialized(MAFwException): 

71 """Exception raised when attempting to run a not initialized Runner.""" 

72 

73 pass 

74 

75 

76class InvalidSteeringFile(MAFwException): 

77 """Exception raised when validating an invalid steering file""" 

78 

79 pass 

80 

81 

82class ValidationIssue(InvalidSteeringFile): 

83 """Base class for steering validation issues.""" 

84 

85 def __init__(self, message: str) -> None: 

86 super().__init__(message) 

87 

88 

89class MissingProcessorsToRunIssue(ValidationIssue): 

90 """Issue raised when the steering file does not declare ``processors_to_run``.""" 

91 

92 def __init__(self) -> None: 

93 super().__init__('Missing processors_to_run') 

94 

95 

96class ProcessorsToRunNotListIssue(ValidationIssue): 

97 """Issue raised when ``processors_to_run`` is not a list.""" 

98 

99 def __init__(self) -> None: 

100 super().__init__('processors_to_run must be a list') 

101 

102 

103class MissingUserInterfaceSectionIssue(ValidationIssue): 

104 """Issue raised when the ``UserInterface`` section is missing.""" 

105 

106 def __init__(self) -> None: 

107 super().__init__('Missing UserInterface section') 

108 

109 

110class UnknownProcessorsToRunEntryIssue(ValidationIssue): 

111 """Issue raised when a processor reference in ``processors_to_run`` cannot be resolved.""" 

112 

113 def __init__(self, entry: str) -> None: 

114 super().__init__(f'Processor reference {entry} not defined') 

115 

116 

117class UnknownGroupMemberIssue(ValidationIssue): 

118 """Issue raised when a group references an unknown processor or nested group.""" 

119 

120 def __init__(self, group: str, member: str) -> None: 

121 super().__init__(f"Group '{group}' references unknown processor or group '{member}'") 

122 

123 

124class DuplicateReplicaIssue(ValidationIssue): 

125 """Issue raised when a processor declares duplicate replica identifiers.""" 

126 

127 def __init__(self, base: str, replica: str) -> None: 

128 super().__init__(f"Duplicate replica identifier '{replica}' for processor '{base}'") 

129 

130 

131class CyclicGroupIssue(ValidationIssue): 

132 """Issue raised when cyclic dependencies exist within processor groups.""" 

133 

134 def __init__(self, node: str) -> None: 

135 super().__init__(f"Cyclic group dependency detected at '{node}'") 

136 

137 

138class InvalidFilterConditionIssue(ValidationIssue): 

139 """Issue raised when a filter condition is incomplete or invalid.""" 

140 

141 def __init__( 

142 self, 

143 processor: str, 

144 model: str, 

145 condition: str, 

146 *, 

147 field_name: str | None = None, 

148 reason: str | None = None, 

149 ) -> None: 

150 descriptor = f"Condition '{condition}' for model '{model}' in processor '{processor}'" 

151 if field_name: 

152 descriptor += f" field '{field_name}'" 

153 descriptor += ' is invalid' 

154 if reason: 154 ↛ 156line 154 didn't jump to line 156 because the condition on line 154 was always true

155 descriptor += f': {reason}' 

156 super().__init__(descriptor) 

157 

158 

159class InvalidFilterLogicIssue(ValidationIssue): 

160 """Issue raised when a filter logic expression is invalid.""" 

161 

162 def __init__(self, processor: str, target: str, *, detail: str | None = None) -> None: 

163 descriptor = f"Logic expression for {target} on processor '{processor}' is invalid" 

164 if detail: 164 ↛ 166line 164 didn't jump to line 166 because the condition on line 164 was always true

165 descriptor += f': {detail}' 

166 super().__init__(descriptor) 

167 

168 

169class UnknownProcessor(MAFwException): 

170 """Exception raised when an attempt is made to create an unknown processor""" 

171 

172 pass 

173 

174 

175class UnknownProcessorGroup(MAFwException): 

176 """Exception raised when an attempt is made to create an unknown processor group""" 

177 

178 pass 

179 

180 

181class UnknownDBEngine(MAFwException): 

182 """Exception raised when the user provided an unknown db engine""" 

183 

184 pass 

185 

186 

187class MissingDatabase(MAFwException): 

188 """Exception raised when a processor requiring a database connection is being operated without a database""" 

189 

190 

191class MissingAttribute(MAFwException): 

192 """Exception raised when an attempt is made to execute a statement without a required parameter/attributes""" 

193 

194 

195class ParserConfigurationError(MAFwException): 

196 """Exception raised when an error occurred during the configuration of a filename parser""" 

197 

198 

199class ParsingError(MAFwException): 

200 """Exception raised when a regular expression parsing failed""" 

201 

202 

203class MissingSQLStatement(MAFwException): 

204 """Exception raised when a Trigger is created without any SQL statements.""" 

205 

206 

207class UnsupportedDatabaseError(Exception): 

208 """Error raised when a feature is not supported by the database.""" 

209 

210 

211class ModelError(MAFwException): 

212 """Exception raised when an error in a DB Model class occurs""" 

213 

214 

215class MissingOptionalDependency(UserWarning): 

216 """UserWarning raised when an optional dependency is required""" 

217 

218 

219class PlotterMixinNotInitialized(MAFwException): 

220 """Exception raised when a plotter mixin has not properly initialized"""