88 DurableExecutionInvocationInput ,
99 DurableExecutionInvocationInputWithClient ,
1010 DurableExecutionInvocationOutput ,
11- InitialExecutionState ,
11+ InitialExecutionState , InvocationStatus ,
1212)
1313
1414from aws_durable_execution_sdk_python_testing .exceptions import (
1515 DurableFunctionsTestError ,
1616)
1717from aws_durable_execution_sdk_python_testing .model import LambdaContext
1818
19-
2019if TYPE_CHECKING :
2120 from collections .abc import Callable
2221
@@ -55,17 +54,17 @@ def create_test_lambda_context() -> LambdaContext:
5554
5655class Invoker (Protocol ):
5756 def create_invocation_input (
58- self , execution : Execution
57+ self , execution : Execution
5958 ) -> DurableExecutionInvocationInput : ... # pragma: no cover
6059
6160 def invoke (
62- self ,
63- function_name : str ,
64- input : DurableExecutionInvocationInput ,
61+ self ,
62+ function_name : str ,
63+ input : DurableExecutionInvocationInput ,
6564 ) -> DurableExecutionInvocationOutput : ... # pragma: no cover
6665
6766 def update_endpoint (
68- self , endpoint_url : str , region_name : str
67+ self , endpoint_url : str , region_name : str
6968 ) -> None : ... # pragma: no cover
7069
7170
@@ -75,7 +74,7 @@ def __init__(self, handler: Callable, service_client: InMemoryServiceClient):
7574 self .service_client = service_client
7675
7776 def create_invocation_input (
78- self , execution : Execution
77+ self , execution : Execution
7978 ) -> DurableExecutionInvocationInput :
8079 return DurableExecutionInvocationInputWithClient (
8180 durable_execution_arn = execution .durable_execution_arn ,
@@ -90,9 +89,9 @@ def create_invocation_input(
9089 )
9190
9291 def invoke (
93- self ,
94- function_name : str , # noqa: ARG002
95- input : DurableExecutionInvocationInput ,
92+ self ,
93+ function_name : str , # noqa: ARG002
94+ input : DurableExecutionInvocationInput ,
9695 ) -> DurableExecutionInvocationOutput :
9796 # TODO: reasses if function_name will be used in future
9897 input_with_client = DurableExecutionInvocationInputWithClient .from_durable_execution_invocation_input (
@@ -126,7 +125,7 @@ def update_endpoint(self, endpoint_url: str, region_name: str) -> None:
126125 )
127126
128127 def create_invocation_input (
129- self , execution : Execution
128+ self , execution : Execution
130129 ) -> DurableExecutionInvocationInput :
131130 return DurableExecutionInvocationInput (
132131 durable_execution_arn = execution .durable_execution_arn ,
@@ -139,21 +138,111 @@ def create_invocation_input(
139138 )
140139
141140 def invoke (
142- self ,
143- function_name : str ,
144- input : DurableExecutionInvocationInput ,
141+ self ,
142+ function_name : str ,
143+ input : DurableExecutionInvocationInput ,
145144 ) -> DurableExecutionInvocationOutput :
146- # TODO: wrap ResourceNotFoundException from lambda in ResourceNotFoundException from this lib
147- response = self .lambda_client .invoke (
148- FunctionName = function_name ,
149- InvocationType = "RequestResponse" , # Synchronous invocation
150- Payload = json .dumps (input .to_dict (), default = str ),
145+ """Invoke AWS Lambda function and return durable execution result.
146+
147+ Args:
148+ function_name: Name of the Lambda function to invoke
149+ input: Durable execution invocation input
150+
151+ Returns:
152+ DurableExecutionInvocationOutput: Result of the function execution
153+
154+ Raises:
155+ ResourceNotFoundException: If function does not exist
156+ InvalidParameterValueException: If parameters are invalid
157+ DurableFunctionsTestError: For other invocation failures
158+ """
159+ from aws_durable_execution_sdk_python_testing .exceptions import (
160+ ResourceNotFoundException ,
161+ InvalidParameterValueException ,
151162 )
152163
153- # very simplified placeholder lol
154- if response ["StatusCode" ] == 200 : # noqa: PLR2004
155- json_response = json .loads (response ["Payload" ].read ().decode ("utf-8" ))
156- return DurableExecutionInvocationOutput .from_dict (json_response )
164+ # Parameter validation
165+ if not function_name or not function_name .strip ():
166+ msg = "Function name is required"
167+ raise InvalidParameterValueException (msg )
168+
169+ try :
170+ # Invoke AWS Lambda function using standard invoke method
171+ response = self .lambda_client .invoke (
172+ FunctionName = function_name ,
173+ InvocationType = "RequestResponse" , # Synchronous invocation
174+ Payload = json .dumps (input .to_dict (), default = str ),
175+ )
157176
158- msg : str = f"Lambda invocation failed with status code: { response ['StatusCode' ]} , { response ['Payload' ]= } "
159- raise DurableFunctionsTestError (msg )
177+ # Check HTTP status code
178+ status_code = response .get ("StatusCode" )
179+ if status_code not in (200 , 202 , 204 ):
180+ msg = f"Lambda invocation failed with status code: { status_code } "
181+ raise DurableFunctionsTestError (msg )
182+
183+ # Check for function errors
184+ if "FunctionError" in response :
185+ error_payload = response ["Payload" ].read ().decode ("utf-8" )
186+ msg = f"Lambda invocation failed with status { status_code } : { error_payload } "
187+ raise DurableFunctionsTestError (msg )
188+
189+ # Parse response payload
190+ response_payload = response ["Payload" ].read ().decode ("utf-8" )
191+ response_dict = json .loads (response_payload )
192+
193+ # Convert to DurableExecutionInvocationOutput
194+ return DurableExecutionInvocationOutput .from_dict (response_dict )
195+
196+ except self .lambda_client .exceptions .ResourceNotFoundException as e :
197+ msg = f"Function not found: { function_name } "
198+ raise ResourceNotFoundException (msg ) from e
199+ except self .lambda_client .exceptions .InvalidParameterValueException as e :
200+ msg = f"Invalid parameter: { e } "
201+ raise InvalidParameterValueException (msg ) from e
202+ except (
203+ self .lambda_client .exceptions .TooManyRequestsException ,
204+ self .lambda_client .exceptions .ServiceException ,
205+ self .lambda_client .exceptions .ResourceConflictException ,
206+ self .lambda_client .exceptions .InvalidRequestContentException ,
207+ self .lambda_client .exceptions .RequestTooLargeException ,
208+ self .lambda_client .exceptions .UnsupportedMediaTypeException ,
209+ self .lambda_client .exceptions .InvalidRuntimeException ,
210+ self .lambda_client .exceptions .InvalidZipFileException ,
211+ self .lambda_client .exceptions .ResourceNotReadyException ,
212+ self .lambda_client .exceptions .SnapStartTimeoutException ,
213+ self .lambda_client .exceptions .SnapStartNotReadyException ,
214+ self .lambda_client .exceptions .SnapStartException ,
215+ self .lambda_client .exceptions .RecursiveInvocationException ,
216+ ) as e :
217+ msg = f"Lambda invocation failed: { e } "
218+ raise DurableFunctionsTestError (msg ) from e
219+ except (
220+ self .lambda_client .exceptions .InvalidSecurityGroupIDException ,
221+ self .lambda_client .exceptions .EC2ThrottledException ,
222+ self .lambda_client .exceptions .EFSMountConnectivityException ,
223+ self .lambda_client .exceptions .SubnetIPAddressLimitReachedException ,
224+ self .lambda_client .exceptions .EC2UnexpectedException ,
225+ self .lambda_client .exceptions .InvalidSubnetIDException ,
226+ self .lambda_client .exceptions .EC2AccessDeniedException ,
227+ self .lambda_client .exceptions .EFSIOException ,
228+ self .lambda_client .exceptions .ENILimitReachedException ,
229+ self .lambda_client .exceptions .EFSMountTimeoutException ,
230+ self .lambda_client .exceptions .EFSMountFailureException ,
231+ ) as e :
232+ msg = f"Lambda infrastructure error: { e } "
233+ raise DurableFunctionsTestError (msg ) from e
234+ except (
235+ self .lambda_client .exceptions .KMSAccessDeniedException ,
236+ self .lambda_client .exceptions .KMSDisabledException ,
237+ self .lambda_client .exceptions .KMSNotFoundException ,
238+ self .lambda_client .exceptions .KMSInvalidStateException ,
239+ ) as e :
240+ msg = f"Lambda KMS error: { e } "
241+ raise DurableFunctionsTestError (msg ) from e
242+ except Exception as e :
243+ # Handle any remaining exceptions, including custom ones like DurableExecutionAlreadyStartedException
244+ if "DurableExecutionAlreadyStartedException" in str (type (e )):
245+ msg = f"Durable execution already started: { e } "
246+ raise DurableFunctionsTestError (msg ) from e
247+ msg = f"Unexpected error during Lambda invocation: { e } "
248+ raise DurableFunctionsTestError (msg ) from e
0 commit comments