pumpwood_communication.exceptions
Define PumpWood exceptions to be treated as API errors.
Define specific errors for the PumpWood platform. These errors are handled explicitly and do not result in default 500 responses.
1"""Define PumpWood exceptions to be treated as API errors. 2 3Define specific errors for the PumpWood platform. These errors are handled 4explicitly and do not result in default 500 responses. 5""" 6from typing import Any 7from loguru import logger 8 9 10class PumpWoodException(Exception): # NOQA 11 """Special exception used in PumpWood systems. 12 13 It permits handling raises in applications by serializing responses 14 with ``to_dict`` and exposing the HTTP status as ``status_code``. 15 """ 16 17 status_code: int = 400 18 """PumpWoodException will return status 400 on Pumpwood backend.""" 19 20 message: str 21 """Message associated with raise.""" 22 23 payload: dict 24 """Dictionary payload returned by ``to_dict`` and used to format 25 the message string.""" 26 27 i8n_object: None 28 """I8n object used to translate the message.""" 29 30 was_translated: bool 31 """If the message was translated.""" 32 33 tag: str 34 """Tag used to disambiguate translation context.""" 35 36 parallel: bool 37 """If error was raised on a parallel request.""" 38 39 def __repr__(self): 40 """@private.""" 41 message_fmt = self.format_message() 42 template = "{class_name}[status_code={status_code}]: " + \ 43 "{message_fmt}\nerror payload={payload}" 44 return template.format( 45 class_name=self.__class__.__name__, 46 status_code=self.status_code, 47 message_fmt=message_fmt, 48 payload=self.payload) 49 50 def __str__(self): 51 """@private.""" 52 message_fmt = self.format_message() 53 template = "{class_name}[status_code={status_code}]: " + \ 54 "{message_fmt}\nerror payload={payload}" 55 return template.format( 56 class_name=self.__class__.__name__, 57 status_code=self.status_code, 58 message_fmt=message_fmt, 59 payload=self.payload) 60 61 def __init__(self, message: str, payload: dict = None, 62 status_code: int = None, tag: str = '', 63 parallel: bool = False, i8n_object: None = None, 64 was_translated: bool = False): 65 """Initialize the PumpWood exception. 66 67 Args: 68 message (str): 69 Message formatted with payload data using ``{key}`` 70 placeholders. 71 payload (dict): 72 Payload data passed as a dictionary. Returned in 73 ``to_dict`` and used to format the message. 74 Defaults to None. 75 status_code (int): 76 HTTP status code override. Defaults to None. 77 i8n_object (None): 78 I8n object used to translate the message. 79 Defaults to None. 80 tag (str): 81 Tag used to disambiguate translation context. 82 Defaults to empty string. 83 parallel (bool): 84 Whether the error occurred during parallel work. 85 Defaults to False. 86 """ 87 Exception.__init__(self) 88 89 # Initialize payload to avoid mutable default issues 90 if payload is None: 91 payload = {} 92 93 self.message = message 94 if status_code is not None: 95 self.status_code = status_code 96 self.payload = payload 97 self.i8n_object = i8n_object 98 self.was_translated = was_translated 99 self.tag = tag 100 self.parallel = parallel 101 102 def format_message(self) -> str: 103 """Format exception message using payload data. 104 105 Substitute placeholders at exception message with payload. 106 107 Returns: 108 str: 109 Message with placeholders substituted from payload data. 110 """ 111 try: 112 # If i8n_object is not None and was_translated is False, 113 # use it to translate the message 114 message = self.message 115 if (self.i8n_object is not None) and (not self.was_translated): 116 message = self.i8n_object.t( 117 sentence=self.message, tag=self.tag) 118 return message.format(**self.payload) 119 except Exception: 120 return self.message + "\n** format error **" 121 122 def to_dict(self) -> dict[str, Any]: 123 """Serialize exception object for API response. 124 125 Returns: 126 dict[str, Any]: 127 Dictionary with keys: 128 - **payload [dict]:** Payload associated with the raise. 129 - **type [str]:** Name of the exception class. 130 - **message_not_fmt [str]:** Message without payload 131 substitution. 132 - **message [str]:** Message formatted with payload data. 133 - **status_code [int]:** HTTP status code for the exception. 134 - **translate [bool]:** Whether the message should be 135 translated. 136 - **tag [str]:** Tag used to disambiguate translation 137 context. 138 - **parallel [bool]:** Whether the error was from parallel 139 work. 140 """ 141 message_fmt = self.format_message() 142 rv = { 143 "__error__": 'PumpWoodException', 144 "type": self.__class__.__name__, 145 "payload": self.payload, 146 "message_not_fmt": self.message, 147 "message": message_fmt, 148 "status_code": self.status_code, 149 "was_translated": self.was_translated, 150 "tag": self.tag, 151 "parallel": self.parallel} 152 return rv 153 154 155class PumpWoodDataLoadingException(PumpWoodException): 156 """Problem when loading data at dataloaders and to_load models.""" 157 158 pass 159 160 161class PumpWoodDatabaseError(PumpWoodException): 162 """Errors raised by Postgres and not treated by other handlers.""" 163 164 pass 165 166 167class PumpWoodUniqueDatabaseError(PumpWoodException): 168 """Unique errors raised by Postgres.""" 169 170 pass 171 172 173class PumpWoodDataTransformationException(PumpWoodException): 174 """Problem when transforming model data.""" 175 176 pass 177 178 179class PumpWoodWrongParameters(PumpWoodException): 180 """Invalid or missing request parameters.""" 181 182 pass 183 184 185class PumpWoodObjectSavingException(PumpWoodException): 186 """Problem when saving object data.""" 187 188 pass 189 190 191class PumpWoodObjectDeleteException(PumpWoodException): 192 """Problem when deleting object data.""" 193 194 pass 195 196 197class PumpWoodActionArgsException(PumpWoodException): 198 """Missing arguments to perform action.""" 199 200 pass 201 202 203class PumpWoodUnauthorized(PumpWoodException): 204 """User is unauthorized to perform the action.""" 205 206 status_code = 401 207 208 209class PumpWoodForbidden(PumpWoodException): 210 """Action is not permitted.""" 211 212 status_code = 403 213 214 215class PumpWoodObjectDoesNotExist(PumpWoodException): 216 """Object not found in database.""" 217 218 status_code = 404 219 220 221class PumpWoodQueryException(PumpWoodException): 222 """Problem when querying data, like wrong fields or operators.""" 223 224 pass 225 226 227class PumpWoodIntegrityError(PumpWoodException): 228 """Problem when saving data due to IntegrityError.""" 229 230 pass 231 232 233class PumpWoodNotImplementedError(PumpWoodException): 234 """Feature or operation is not implemented.""" 235 236 pass 237 238 239class PumpWoodMicroserviceUnavailableError(PumpWoodException): 240 """Microservice is unavailable or was not deployed.""" 241 242 pass 243 244 245class PumpWoodMFAError(PumpWoodException): 246 """Problem when using MFA.""" 247 248 pass 249 250 251class PumpWoodJSONLoadError(PumpWoodException): 252 """Problem loading JSON data from a request.""" 253 254 pass 255 256 257class PumpWoodCacheError(PumpWoodException): 258 """Problem using the PumpWood cache.""" 259 260 pass 261 262 263class PumpWoodOtherException(PumpWoodException): 264 """Unhandled or unmapped server error.""" 265 266 status_code = 500 267 268 def __init__(self, message: str, payload: dict = None, 269 status_code: int = None, was_translated: bool = False, 270 tag: str = '', parallel: bool = False): 271 """Initialize PumpWoodOtherException. 272 273 Args: 274 message (str): 275 Message formatted with payload data using ``{key}`` 276 placeholders. Truncated to 1000 characters. 277 payload (dict): 278 Payload data passed as a dictionary. Returned in 279 ``to_dict`` and used to format the message. 280 Defaults to None. 281 was_translated (bool): 282 If the message was translated. Defaults to False. 283 tag (str): 284 Tag used to disambiguate translation context. 285 Defaults to empty string. 286 status_code (int): 287 Change the default status code of the exception. 288 Defaults to None. 289 parallel (bool): 290 Whether the error occurred during parallel work. 291 Defaults to False. 292 """ 293 Exception.__init__(self) 294 295 # Initialize payload to avoid mutable default issues 296 if payload is None: 297 payload = {} 298 299 # Limit size of the error, it is expected that other exceptions 300 # may have long text from kong or other between services 301 self.message = message[:1000] 302 303 if status_code is not None: 304 self.status_code = status_code 305 self.payload = payload 306 307 # Other exceptions are never translated are never translated 308 self.was_translated = False 309 self.tag = tag 310 self.parallel = parallel 311 312 def format_message(self) -> str: 313 """Return the message without formatting. 314 315 Other exceptions are never translated, so the message is not formatted 316 and returned as is. 317 """ 318 return self.message 319 320 321class AirflowMicroServiceException(PumpWoodException): 322 """Exception raised from AirflowMicroService.""" 323 324 pass 325 326 327exceptions_dict = { 328 "PumpWoodException": PumpWoodException, 329 "PumpWoodDataLoadingException": PumpWoodDataLoadingException, 330 "PumpWoodDatabaseError": PumpWoodDatabaseError, 331 "PumpWoodDataTransformationException": PumpWoodDataTransformationException, 332 "PumpWoodWrongParameters": PumpWoodWrongParameters, 333 "PumpWoodObjectSavingException": PumpWoodObjectSavingException, 334 "PumpWoodObjectDeleteException": PumpWoodObjectDeleteException, 335 "PumpWoodActionArgsException": PumpWoodActionArgsException, 336 "PumpWoodUnauthorized": PumpWoodUnauthorized, 337 "PumpWoodForbidden": PumpWoodForbidden, 338 "PumpWoodObjectDoesNotExist": PumpWoodObjectDoesNotExist, 339 "PumpWoodQueryException": PumpWoodQueryException, 340 "PumpWoodIntegrityError": PumpWoodIntegrityError, 341 "PumpWoodNotImplementedError": PumpWoodNotImplementedError, 342 "PumpWoodMicroserviceUnavailableError": 343 PumpWoodMicroserviceUnavailableError, 344 "PumpWoodMFAError": PumpWoodMFAError, 345 "PumpWoodJSONLoadError": PumpWoodJSONLoadError, 346 "PumpWoodCacheError": PumpWoodCacheError, 347 "PumpWoodOtherException": PumpWoodOtherException, 348 "AirflowMicroServiceException": AirflowMicroServiceException, 349 "PumpWoodUniqueDatabaseError": PumpWoodUniqueDatabaseError 350} 351""" 352Dictionary mapping exception class names to types. 353 354Used by backends and microservices to re-raise PumpWood exceptions. 355""" 356 357 358def raise_pumpwood_exception(exception_name: str, message: str, 359 payload: dict = None, status_code: int = None, 360 translate: bool = False, tag: str = '', 361 parallel: bool = False): 362 """Raise a PumpWood exception based on its name. 363 364 Args: 365 exception_name (str): 366 Name of the exception to be retrieved and raised. 367 message (str): 368 The error message associated with the exception. 369 payload (dict): 370 A dictionary containing additional data for the exception. 371 Defaults to None. 372 status_code (int): 373 HTTP status code to be returned. Defaults to None. 374 translate (bool): 375 Whether the message should be translated. Defaults to False. 376 tag (str): 377 Tag used to disambiguate translation context. 378 Defaults to empty string. 379 parallel (bool): 380 If the exception happened during parallel processing. 381 Defaults to False. 382 383 Returns: 384 None: 385 This function does not return; it always raises an exception. 386 387 Raises: 388 PumpWoodOtherException: 389 If ``exception_name`` is not found in the registry. 390 PumpWoodException: 391 The specific exception mapped to ``exception_name``. 392 """ 393 # Initialize payload to avoid mutable default issues 394 if payload is None: 395 payload = {} 396 397 pumpwood_exception = exceptions_dict.get(exception_name) 398 if pumpwood_exception is None: 399 msg = ( 400 "exception_name [{exception_name}] not found in PumpWood " 401 "Exceptions. Check implementation") 402 logger.error( 403 msg.format(exception_name=exception_name)) 404 raise PumpWoodOtherException( 405 msg.format(exception_name=exception_name), 406 payload=payload, status_code=status_code, 407 tag=tag, parallel=parallel) 408 else: 409 raise pumpwood_exception( 410 message=message, payload=payload, status_code=status_code, 411 translate=translate, tag=tag, parallel=parallel) 412 413 414def raise_from_dict(exception_dict: dict): 415 """Raise a PumpWood exception from a serialized error dict. 416 417 Accepts output from `PumpWoodException.to_dict()` or compatible 418 payloads using `type` as the exception class name. 419 420 Args: 421 exception_dict (dict): 422 Serialized exception data. Expected keys are `type` (or 423 legacy `exception_name`), `message_not_fmt`, `payload`, 424 `status_code`, `translate`, `tag`, and `parallel`. 425 426 Returns: 427 None: 428 This function does not return as it always raises an 429 exception. 430 431 Raises: 432 PumpWoodOtherException: 433 If the specified exception type is not found in the 434 registry. 435 PumpWoodException: 436 The specific exception mapped to the exception type. 437 """ 438 exception_name = exception_dict.get("type") or exception_dict.get( 439 "exception_name") 440 message_not_fmt = exception_dict.get("message_not_fmt") 441 payload = exception_dict.get("payload") 442 status_code = exception_dict.get("status_code") 443 translate = exception_dict.get("translate", False) 444 tag = exception_dict.get("tag", '') 445 parallel = exception_dict.get("parallel", False) 446 447 raise_pumpwood_exception( 448 exception_name=exception_name, 449 message=message_not_fmt, payload=payload, status_code=status_code, 450 translate=translate, tag=tag, parallel=parallel)
11class PumpWoodException(Exception): # NOQA 12 """Special exception used in PumpWood systems. 13 14 It permits handling raises in applications by serializing responses 15 with ``to_dict`` and exposing the HTTP status as ``status_code``. 16 """ 17 18 status_code: int = 400 19 """PumpWoodException will return status 400 on Pumpwood backend.""" 20 21 message: str 22 """Message associated with raise.""" 23 24 payload: dict 25 """Dictionary payload returned by ``to_dict`` and used to format 26 the message string.""" 27 28 i8n_object: None 29 """I8n object used to translate the message.""" 30 31 was_translated: bool 32 """If the message was translated.""" 33 34 tag: str 35 """Tag used to disambiguate translation context.""" 36 37 parallel: bool 38 """If error was raised on a parallel request.""" 39 40 def __repr__(self): 41 """@private.""" 42 message_fmt = self.format_message() 43 template = "{class_name}[status_code={status_code}]: " + \ 44 "{message_fmt}\nerror payload={payload}" 45 return template.format( 46 class_name=self.__class__.__name__, 47 status_code=self.status_code, 48 message_fmt=message_fmt, 49 payload=self.payload) 50 51 def __str__(self): 52 """@private.""" 53 message_fmt = self.format_message() 54 template = "{class_name}[status_code={status_code}]: " + \ 55 "{message_fmt}\nerror payload={payload}" 56 return template.format( 57 class_name=self.__class__.__name__, 58 status_code=self.status_code, 59 message_fmt=message_fmt, 60 payload=self.payload) 61 62 def __init__(self, message: str, payload: dict = None, 63 status_code: int = None, tag: str = '', 64 parallel: bool = False, i8n_object: None = None, 65 was_translated: bool = False): 66 """Initialize the PumpWood exception. 67 68 Args: 69 message (str): 70 Message formatted with payload data using ``{key}`` 71 placeholders. 72 payload (dict): 73 Payload data passed as a dictionary. Returned in 74 ``to_dict`` and used to format the message. 75 Defaults to None. 76 status_code (int): 77 HTTP status code override. Defaults to None. 78 i8n_object (None): 79 I8n object used to translate the message. 80 Defaults to None. 81 tag (str): 82 Tag used to disambiguate translation context. 83 Defaults to empty string. 84 parallel (bool): 85 Whether the error occurred during parallel work. 86 Defaults to False. 87 """ 88 Exception.__init__(self) 89 90 # Initialize payload to avoid mutable default issues 91 if payload is None: 92 payload = {} 93 94 self.message = message 95 if status_code is not None: 96 self.status_code = status_code 97 self.payload = payload 98 self.i8n_object = i8n_object 99 self.was_translated = was_translated 100 self.tag = tag 101 self.parallel = parallel 102 103 def format_message(self) -> str: 104 """Format exception message using payload data. 105 106 Substitute placeholders at exception message with payload. 107 108 Returns: 109 str: 110 Message with placeholders substituted from payload data. 111 """ 112 try: 113 # If i8n_object is not None and was_translated is False, 114 # use it to translate the message 115 message = self.message 116 if (self.i8n_object is not None) and (not self.was_translated): 117 message = self.i8n_object.t( 118 sentence=self.message, tag=self.tag) 119 return message.format(**self.payload) 120 except Exception: 121 return self.message + "\n** format error **" 122 123 def to_dict(self) -> dict[str, Any]: 124 """Serialize exception object for API response. 125 126 Returns: 127 dict[str, Any]: 128 Dictionary with keys: 129 - **payload [dict]:** Payload associated with the raise. 130 - **type [str]:** Name of the exception class. 131 - **message_not_fmt [str]:** Message without payload 132 substitution. 133 - **message [str]:** Message formatted with payload data. 134 - **status_code [int]:** HTTP status code for the exception. 135 - **translate [bool]:** Whether the message should be 136 translated. 137 - **tag [str]:** Tag used to disambiguate translation 138 context. 139 - **parallel [bool]:** Whether the error was from parallel 140 work. 141 """ 142 message_fmt = self.format_message() 143 rv = { 144 "__error__": 'PumpWoodException', 145 "type": self.__class__.__name__, 146 "payload": self.payload, 147 "message_not_fmt": self.message, 148 "message": message_fmt, 149 "status_code": self.status_code, 150 "was_translated": self.was_translated, 151 "tag": self.tag, 152 "parallel": self.parallel} 153 return rv
Special exception used in PumpWood systems.
It permits handling raises in applications by serializing responses
with to_dict and exposing the HTTP status as status_code.
62 def __init__(self, message: str, payload: dict = None, 63 status_code: int = None, tag: str = '', 64 parallel: bool = False, i8n_object: None = None, 65 was_translated: bool = False): 66 """Initialize the PumpWood exception. 67 68 Args: 69 message (str): 70 Message formatted with payload data using ``{key}`` 71 placeholders. 72 payload (dict): 73 Payload data passed as a dictionary. Returned in 74 ``to_dict`` and used to format the message. 75 Defaults to None. 76 status_code (int): 77 HTTP status code override. Defaults to None. 78 i8n_object (None): 79 I8n object used to translate the message. 80 Defaults to None. 81 tag (str): 82 Tag used to disambiguate translation context. 83 Defaults to empty string. 84 parallel (bool): 85 Whether the error occurred during parallel work. 86 Defaults to False. 87 """ 88 Exception.__init__(self) 89 90 # Initialize payload to avoid mutable default issues 91 if payload is None: 92 payload = {} 93 94 self.message = message 95 if status_code is not None: 96 self.status_code = status_code 97 self.payload = payload 98 self.i8n_object = i8n_object 99 self.was_translated = was_translated 100 self.tag = tag 101 self.parallel = parallel
Initialize the PumpWood exception.
Arguments:
- message (str): Message formatted with payload data using
{key}placeholders. - payload (dict): Payload data passed as a dictionary. Returned in
to_dictand used to format the message. Defaults to None. - status_code (int): HTTP status code override. Defaults to None.
- i8n_object (None): I8n object used to translate the message. Defaults to None.
- tag (str): Tag used to disambiguate translation context. Defaults to empty string.
- parallel (bool): Whether the error occurred during parallel work. Defaults to False.
103 def format_message(self) -> str: 104 """Format exception message using payload data. 105 106 Substitute placeholders at exception message with payload. 107 108 Returns: 109 str: 110 Message with placeholders substituted from payload data. 111 """ 112 try: 113 # If i8n_object is not None and was_translated is False, 114 # use it to translate the message 115 message = self.message 116 if (self.i8n_object is not None) and (not self.was_translated): 117 message = self.i8n_object.t( 118 sentence=self.message, tag=self.tag) 119 return message.format(**self.payload) 120 except Exception: 121 return self.message + "\n** format error **"
Format exception message using payload data.
Substitute placeholders at exception message with payload.
Returns:
str: Message with placeholders substituted from payload data.
123 def to_dict(self) -> dict[str, Any]: 124 """Serialize exception object for API response. 125 126 Returns: 127 dict[str, Any]: 128 Dictionary with keys: 129 - **payload [dict]:** Payload associated with the raise. 130 - **type [str]:** Name of the exception class. 131 - **message_not_fmt [str]:** Message without payload 132 substitution. 133 - **message [str]:** Message formatted with payload data. 134 - **status_code [int]:** HTTP status code for the exception. 135 - **translate [bool]:** Whether the message should be 136 translated. 137 - **tag [str]:** Tag used to disambiguate translation 138 context. 139 - **parallel [bool]:** Whether the error was from parallel 140 work. 141 """ 142 message_fmt = self.format_message() 143 rv = { 144 "__error__": 'PumpWoodException', 145 "type": self.__class__.__name__, 146 "payload": self.payload, 147 "message_not_fmt": self.message, 148 "message": message_fmt, 149 "status_code": self.status_code, 150 "was_translated": self.was_translated, 151 "tag": self.tag, 152 "parallel": self.parallel} 153 return rv
Serialize exception object for API response.
Returns:
dict[str, Any]: Dictionary with keys:
- payload [dict]: Payload associated with the raise.
- type [str]: Name of the exception class.
- message_not_fmt [str]: Message without payload substitution.
- message [str]: Message formatted with payload data.
- status_code [int]: HTTP status code for the exception.
- translate [bool]: Whether the message should be translated.
- tag [str]: Tag used to disambiguate translation context.
- parallel [bool]: Whether the error was from parallel work.
156class PumpWoodDataLoadingException(PumpWoodException): 157 """Problem when loading data at dataloaders and to_load models.""" 158 159 pass
Problem when loading data at dataloaders and to_load models.
162class PumpWoodDatabaseError(PumpWoodException): 163 """Errors raised by Postgres and not treated by other handlers.""" 164 165 pass
Errors raised by Postgres and not treated by other handlers.
168class PumpWoodUniqueDatabaseError(PumpWoodException): 169 """Unique errors raised by Postgres.""" 170 171 pass
Unique errors raised by Postgres.
174class PumpWoodDataTransformationException(PumpWoodException): 175 """Problem when transforming model data.""" 176 177 pass
Problem when transforming model data.
180class PumpWoodWrongParameters(PumpWoodException): 181 """Invalid or missing request parameters.""" 182 183 pass
Invalid or missing request parameters.
186class PumpWoodObjectSavingException(PumpWoodException): 187 """Problem when saving object data.""" 188 189 pass
Problem when saving object data.
192class PumpWoodObjectDeleteException(PumpWoodException): 193 """Problem when deleting object data.""" 194 195 pass
Problem when deleting object data.
198class PumpWoodActionArgsException(PumpWoodException): 199 """Missing arguments to perform action.""" 200 201 pass
Missing arguments to perform action.
210class PumpWoodForbidden(PumpWoodException): 211 """Action is not permitted.""" 212 213 status_code = 403
Action is not permitted.
Inherited Members
216class PumpWoodObjectDoesNotExist(PumpWoodException): 217 """Object not found in database.""" 218 219 status_code = 404
Object not found in database.
Inherited Members
222class PumpWoodQueryException(PumpWoodException): 223 """Problem when querying data, like wrong fields or operators.""" 224 225 pass
Problem when querying data, like wrong fields or operators.
228class PumpWoodIntegrityError(PumpWoodException): 229 """Problem when saving data due to IntegrityError.""" 230 231 pass
Problem when saving data due to IntegrityError.
234class PumpWoodNotImplementedError(PumpWoodException): 235 """Feature or operation is not implemented.""" 236 237 pass
Feature or operation is not implemented.
Problem when using MFA.
252class PumpWoodJSONLoadError(PumpWoodException): 253 """Problem loading JSON data from a request.""" 254 255 pass
Problem loading JSON data from a request.
258class PumpWoodCacheError(PumpWoodException): 259 """Problem using the PumpWood cache.""" 260 261 pass
Problem using the PumpWood cache.
264class PumpWoodOtherException(PumpWoodException): 265 """Unhandled or unmapped server error.""" 266 267 status_code = 500 268 269 def __init__(self, message: str, payload: dict = None, 270 status_code: int = None, was_translated: bool = False, 271 tag: str = '', parallel: bool = False): 272 """Initialize PumpWoodOtherException. 273 274 Args: 275 message (str): 276 Message formatted with payload data using ``{key}`` 277 placeholders. Truncated to 1000 characters. 278 payload (dict): 279 Payload data passed as a dictionary. Returned in 280 ``to_dict`` and used to format the message. 281 Defaults to None. 282 was_translated (bool): 283 If the message was translated. Defaults to False. 284 tag (str): 285 Tag used to disambiguate translation context. 286 Defaults to empty string. 287 status_code (int): 288 Change the default status code of the exception. 289 Defaults to None. 290 parallel (bool): 291 Whether the error occurred during parallel work. 292 Defaults to False. 293 """ 294 Exception.__init__(self) 295 296 # Initialize payload to avoid mutable default issues 297 if payload is None: 298 payload = {} 299 300 # Limit size of the error, it is expected that other exceptions 301 # may have long text from kong or other between services 302 self.message = message[:1000] 303 304 if status_code is not None: 305 self.status_code = status_code 306 self.payload = payload 307 308 # Other exceptions are never translated are never translated 309 self.was_translated = False 310 self.tag = tag 311 self.parallel = parallel 312 313 def format_message(self) -> str: 314 """Return the message without formatting. 315 316 Other exceptions are never translated, so the message is not formatted 317 and returned as is. 318 """ 319 return self.message
Unhandled or unmapped server error.
269 def __init__(self, message: str, payload: dict = None, 270 status_code: int = None, was_translated: bool = False, 271 tag: str = '', parallel: bool = False): 272 """Initialize PumpWoodOtherException. 273 274 Args: 275 message (str): 276 Message formatted with payload data using ``{key}`` 277 placeholders. Truncated to 1000 characters. 278 payload (dict): 279 Payload data passed as a dictionary. Returned in 280 ``to_dict`` and used to format the message. 281 Defaults to None. 282 was_translated (bool): 283 If the message was translated. Defaults to False. 284 tag (str): 285 Tag used to disambiguate translation context. 286 Defaults to empty string. 287 status_code (int): 288 Change the default status code of the exception. 289 Defaults to None. 290 parallel (bool): 291 Whether the error occurred during parallel work. 292 Defaults to False. 293 """ 294 Exception.__init__(self) 295 296 # Initialize payload to avoid mutable default issues 297 if payload is None: 298 payload = {} 299 300 # Limit size of the error, it is expected that other exceptions 301 # may have long text from kong or other between services 302 self.message = message[:1000] 303 304 if status_code is not None: 305 self.status_code = status_code 306 self.payload = payload 307 308 # Other exceptions are never translated are never translated 309 self.was_translated = False 310 self.tag = tag 311 self.parallel = parallel
Initialize PumpWoodOtherException.
Arguments:
- message (str): Message formatted with payload data using
{key}placeholders. Truncated to 1000 characters. - payload (dict): Payload data passed as a dictionary. Returned in
to_dictand used to format the message. Defaults to None. - was_translated (bool): If the message was translated. Defaults to False.
- tag (str): Tag used to disambiguate translation context. Defaults to empty string.
- status_code (int): Change the default status code of the exception. Defaults to None.
- parallel (bool): Whether the error occurred during parallel work. Defaults to False.
313 def format_message(self) -> str: 314 """Return the message without formatting. 315 316 Other exceptions are never translated, so the message is not formatted 317 and returned as is. 318 """ 319 return self.message
Return the message without formatting.
Other exceptions are never translated, so the message is not formatted and returned as is.
Inherited Members
322class AirflowMicroServiceException(PumpWoodException): 323 """Exception raised from AirflowMicroService.""" 324 325 pass
Exception raised from AirflowMicroService.
Dictionary mapping exception class names to types.
Used by backends and microservices to re-raise PumpWood exceptions.
359def raise_pumpwood_exception(exception_name: str, message: str, 360 payload: dict = None, status_code: int = None, 361 translate: bool = False, tag: str = '', 362 parallel: bool = False): 363 """Raise a PumpWood exception based on its name. 364 365 Args: 366 exception_name (str): 367 Name of the exception to be retrieved and raised. 368 message (str): 369 The error message associated with the exception. 370 payload (dict): 371 A dictionary containing additional data for the exception. 372 Defaults to None. 373 status_code (int): 374 HTTP status code to be returned. Defaults to None. 375 translate (bool): 376 Whether the message should be translated. Defaults to False. 377 tag (str): 378 Tag used to disambiguate translation context. 379 Defaults to empty string. 380 parallel (bool): 381 If the exception happened during parallel processing. 382 Defaults to False. 383 384 Returns: 385 None: 386 This function does not return; it always raises an exception. 387 388 Raises: 389 PumpWoodOtherException: 390 If ``exception_name`` is not found in the registry. 391 PumpWoodException: 392 The specific exception mapped to ``exception_name``. 393 """ 394 # Initialize payload to avoid mutable default issues 395 if payload is None: 396 payload = {} 397 398 pumpwood_exception = exceptions_dict.get(exception_name) 399 if pumpwood_exception is None: 400 msg = ( 401 "exception_name [{exception_name}] not found in PumpWood " 402 "Exceptions. Check implementation") 403 logger.error( 404 msg.format(exception_name=exception_name)) 405 raise PumpWoodOtherException( 406 msg.format(exception_name=exception_name), 407 payload=payload, status_code=status_code, 408 tag=tag, parallel=parallel) 409 else: 410 raise pumpwood_exception( 411 message=message, payload=payload, status_code=status_code, 412 translate=translate, tag=tag, parallel=parallel)
Raise a PumpWood exception based on its name.
Arguments:
- exception_name (str): Name of the exception to be retrieved and raised.
- message (str): The error message associated with the exception.
- payload (dict): A dictionary containing additional data for the exception. Defaults to None.
- status_code (int): HTTP status code to be returned. Defaults to None.
- translate (bool): Whether the message should be translated. Defaults to False.
- tag (str): Tag used to disambiguate translation context. Defaults to empty string.
- parallel (bool): If the exception happened during parallel processing. Defaults to False.
Returns:
None: This function does not return; it always raises an exception.
Raises:
- PumpWoodOtherException: If
exception_nameis not found in the registry. - PumpWoodException: The specific exception mapped to
exception_name.
415def raise_from_dict(exception_dict: dict): 416 """Raise a PumpWood exception from a serialized error dict. 417 418 Accepts output from `PumpWoodException.to_dict()` or compatible 419 payloads using `type` as the exception class name. 420 421 Args: 422 exception_dict (dict): 423 Serialized exception data. Expected keys are `type` (or 424 legacy `exception_name`), `message_not_fmt`, `payload`, 425 `status_code`, `translate`, `tag`, and `parallel`. 426 427 Returns: 428 None: 429 This function does not return as it always raises an 430 exception. 431 432 Raises: 433 PumpWoodOtherException: 434 If the specified exception type is not found in the 435 registry. 436 PumpWoodException: 437 The specific exception mapped to the exception type. 438 """ 439 exception_name = exception_dict.get("type") or exception_dict.get( 440 "exception_name") 441 message_not_fmt = exception_dict.get("message_not_fmt") 442 payload = exception_dict.get("payload") 443 status_code = exception_dict.get("status_code") 444 translate = exception_dict.get("translate", False) 445 tag = exception_dict.get("tag", '') 446 parallel = exception_dict.get("parallel", False) 447 448 raise_pumpwood_exception( 449 exception_name=exception_name, 450 message=message_not_fmt, payload=payload, status_code=status_code, 451 translate=translate, tag=tag, parallel=parallel)
Raise a PumpWood exception from a serialized error dict.
Accepts output from PumpWoodException.to_dict() or compatible
payloads using type as the exception class name.
Arguments:
- exception_dict (dict): Serialized exception data. Expected keys are
type(or legacyexception_name),message_not_fmt,payload,status_code,translate,tag, andparallel.
Returns:
None: This function does not return as it always raises an exception.
Raises:
- PumpWoodOtherException: If the specified exception type is not found in the registry.
- PumpWoodException: The specific exception mapped to the exception type.