33import re
44from collections .abc import Sequence
55from functools import partial , wraps
6- from typing import Any , Callable
6+ from typing import Any , Callable , Pattern
77
88from botocore .exceptions import ClientError
99
@@ -46,9 +46,16 @@ def __init__(self, message: str = "", raw_error: str = "", error_code: str = "",
4646 'kind'
4747 >>> error.details
4848 'details'
49+ >>> error = SWFError('message', error_code='FooFault')
50+ >>> error.message
51+ 'message'
52+ >>> error.error_code
53+ 'FooFault'
54+ >>> error.details
55+ ''
4956
5057 """
51- Exception .__init__ (self , message , * args )
58+ super () .__init__ (message , * args )
5259
5360 values = raw_error .split (":" , 1 )
5461
@@ -118,18 +125,15 @@ def ignore(*args, **kwargs):
118125REGEX_NESTED_RESOURCE = re .compile (r"Unknown (?:type|execution)[:,]\s*([^ =]+)\s*=" )
119126
120127
121- def match_equals (regex , string , values ) :
128+ def match_equals (regex : Pattern , string : str | None , values : str | Sequence [ str ]) -> bool :
122129 """
123130 Extract a value from a string with a regex and compare it.
124131
125132 :param regex: to extract the value to check.
126- :type regex: _sre.SRE_Pattern (compiled regex)
127133
128134 :param string: that contains the value to extract.
129- :type string: str
130135
131136 :param values: to compare with.
132- :type values: [str]
133137
134138 """
135139 if string is None :
@@ -144,12 +148,11 @@ def match_equals(regex, string, values):
144148 return matched [0 ] in values
145149
146150
147- def is_unknown_resource_raised (error , * args , ** kwargs ):
151+ def is_unknown_resource_raised (error : Exception , * args , ** kwargs ) -> bool :
148152 """
149153 Handler that checks if *error* is an unknown resource fault.
150154
151155 :param error: is the exception to check.
152- :type error: Exception
153156
154157 """
155158 if not isinstance (error , ClientError ):
@@ -158,7 +161,7 @@ def is_unknown_resource_raised(error, *args, **kwargs):
158161 return extract_error_code (error ) == "UnknownResourceFault"
159162
160163
161- def is_unknown (resource : str | Sequence [str ]):
164+ def is_unknown (resource : str | Sequence [str ]) -> Callable :
162165 """
163166 Return a function that checks if *error* is an unknown *resource* fault.
164167
@@ -190,7 +193,7 @@ def wrapped(error, *args, **kwargs):
190193 return wrapped
191194
192195
193- def always (value ) :
196+ def always (value : Any ) -> Callable :
194197 """
195198 Always return *value* whatever arguments it got.
196199
@@ -217,7 +220,7 @@ def wrapped(*args, **kwargs):
217220 return wrapped
218221
219222
220- def generate_resource_not_found_message (error ) :
223+ def generate_resource_not_found_message (error : Exception ) -> str :
221224 error_code = extract_error_code (error )
222225 if error_code != "UnknownResourceFault" :
223226 raise ValueError (f"cannot extract resource from { error } " )
@@ -227,37 +230,43 @@ def generate_resource_not_found_message(error):
227230 return f"Resource { resource [0 ] if resource else 'unknown' } does not exist"
228231
229232
230- def raises (exception , when , extract : Callable [[Any ], str ] = str ):
233+ def raises (
234+ exception : type [Exception ] | type [SWFError ],
235+ when : Callable [[Exception , tuple , dict ], bool ],
236+ extract : Callable [[Any ], str ] = str ,
237+ ):
231238 """
232239 :param exception: to raise when the predicate is True.
233- :type exception: type(Exception)
234-
235240 :param when: predicate to apply.
236- :type when: (error, *args, **kwargs) -> bool
241+ :param extract: function to extract the value from the exception.
237242 """
238243
239244 @wraps (raises )
240245 def raises_closure (error , * args , ** kwargs ):
241246 if when (error , * args , ** kwargs ) is True :
242- raise exception (extract (error )) from None
243- raise error
247+ if isinstance (getattr (error , "response" , None ), dict ) and issubclass (exception , SWFError ):
248+ raise exception (extract_message (error ), error_code = extract_error_code (error )) from error
249+
250+ raise exception (extract (error )) from error
251+ raise error from None
244252
245253 return raises_closure
246254
247255
248- def catch (exceptions , handle_with = None , log = False ):
256+ def catch (
257+ exceptions : type [Exception ] | Sequence [type [Exception ]] | tuple [type [Exception ]],
258+ handle_with : Callable [[Exception , tuple , dict ], Any ] | None = None ,
259+ log : bool = False ,
260+ ):
249261 """
250262 Catch *exceptions*, then eventually handle and log them.
251263
252264 :param exceptions: sequence of exceptions to catch.
253- :type exceptions: Exception | (Exception, )
254265
255266 :param handle_with: handle the exceptions (if handle_with is not None) or
256267 raise them again.
257- :type handle_with: function(err, *args, **kwargs)
258268
259269 :param log: the exception with default logger.
260- :type log: bool
261270
262271 Examples:
263272
@@ -312,10 +321,10 @@ def translate(exceptions, to):
312321
313322 """
314323
315- def throw (err , * args , ** kwargs ):
324+ def throw (err : Exception , * args , ** kwargs ):
316325 if isinstance (getattr (err , "response" , None ), dict ) and issubclass (to , SWFError ):
317- raise to (extract_message (err ), error_code = extract_error_code (err )) from None
318- raise to (extract_message (err ))
326+ raise to (extract_message (err ), error_code = extract_error_code (err )) from err
327+ raise to (extract_message (err )) from err
319328
320329 return catch (exceptions , handle_with = throw )
321330
0 commit comments