|
5 | 5 |
|
6 | 6 | from rdl.data_sources.ChangeTrackingInfo import ChangeTrackingInfo |
7 | 7 | from rdl.data_sources.SourceTableInfo import SourceTableInfo |
8 | | -from rdl.shared import Providers |
| 8 | +from rdl.shared import Providers, Constants |
9 | 9 | from rdl.shared.Utils import prevent_senstive_data_logging |
10 | 10 |
|
11 | 11 |
|
@@ -148,38 +148,45 @@ def __get_data_frame(self, data: [[]], column_names: []): |
148 | 148 | return pandas.DataFrame(data=data, columns=column_names) |
149 | 149 |
|
150 | 150 | def __invoke_lambda(self, pay_load): |
151 | | - self.logger.debug("\nRequest being sent to Lambda:") |
152 | | - self.logger.debug(pay_load) |
153 | | - |
154 | | - lambda_response = self.aws_lambda_client.invoke( |
155 | | - FunctionName=self.connection_data["function"], |
156 | | - InvocationType="RequestResponse", |
157 | | - LogType="None", # |'Tail', Set to Tail to include the execution log in the response |
158 | | - Payload=json.dumps(pay_load).encode(), |
159 | | - ) |
160 | | - |
161 | | - response_status_code = int(lambda_response["StatusCode"]) |
162 | | - response_function_error = lambda_response.get("FunctionError") |
163 | | - self.logger.debug("\nResponse received from Lambda:") |
164 | | - self.logger.debug(f'Response - StatusCode = "{response_status_code}"') |
165 | | - self.logger.debug(f'Response - FunctionError = "{response_function_error}"') |
166 | | - |
167 | | - response_payload = json.loads(lambda_response["Payload"].read()) |
168 | | - |
169 | | - if response_status_code != 200 or response_function_error: |
170 | | - self.logger.error( |
171 | | - f'Error in response from aws lambda {self.connection_data["function"]}' |
172 | | - ) |
173 | | - self.logger.error(f"Response - Status Code = {response_status_code}") |
174 | | - self.logger.error(f"Response - Error Function = {response_function_error}") |
175 | | - self.logger.error(f"Response - Error Details:") |
176 | | - # the below is risky as it may contain actual data if this line is reached in case of a successful result |
177 | | - # however, the same Payload field is used to return actual error details in case of real errors |
178 | | - # i.e. StatusCode is 200 (since AWS could invoke the lambda) |
179 | | - # BUT the lambda barfed with an error and therefore the FunctionError would not be None |
180 | | - self.logger.error(response_payload) |
181 | | - raise Exception( |
182 | | - "Error received when invoking AWS Lambda. See logs for further details." |
| 151 | + max_attempts = Constants.MAX_AWS_LAMBDA_INVOKATION_ATTEMPTS |
| 152 | + response_payload = None |
| 153 | + |
| 154 | + for current_attempt in list(range(1, max_attempts+1, 1)): |
| 155 | + self.logger.debug(f"\nRequest being sent to Lambda, attempt {current_attempt} of {max_attempts}:") |
| 156 | + self.logger.debug(pay_load) |
| 157 | + |
| 158 | + lambda_response = self.aws_lambda_client.invoke( |
| 159 | + FunctionName=self.connection_data["function"], |
| 160 | + InvocationType="RequestResponse", |
| 161 | + LogType="None", # |'Tail', Set to Tail to include the execution log in the response |
| 162 | + Payload=json.dumps(pay_load).encode(), |
183 | 163 | ) |
184 | 164 |
|
| 165 | + response_status_code = int(lambda_response["StatusCode"]) |
| 166 | + response_function_error = lambda_response.get("FunctionError") |
| 167 | + self.logger.debug(f"\nResponse received from Lambda, attempt {current_attempt} of {max_attempts}:") |
| 168 | + self.logger.debug(f'Response - StatusCode = "{response_status_code}"') |
| 169 | + self.logger.debug(f'Response - FunctionError = "{response_function_error}"') |
| 170 | + |
| 171 | + response_payload = json.loads(lambda_response["Payload"].read()) |
| 172 | + |
| 173 | + if response_status_code != 200 or response_function_error: |
| 174 | + self.logger.error( |
| 175 | + f'Error in response from aws lambda \'{self.connection_data["function"]}\', ' |
| 176 | + f'attempt {current_attempt} of {max_attempts}' |
| 177 | + ) |
| 178 | + self.logger.error(f"Response - Status Code = {response_status_code}") |
| 179 | + self.logger.error(f"Response - Error Function = {response_function_error}") |
| 180 | + self.logger.error(f"Response - Error Details:") |
| 181 | + # the below is risky as it may contain actual data if this line is reached in case of success |
| 182 | + # however, the same Payload field is used to return actual error details in case of failure |
| 183 | + # i.e. StatusCode is 200 (since AWS could invoke the lambda) |
| 184 | + # BUT the lambda barfed with an error and therefore the FunctionError would not be None |
| 185 | + self.logger.error(response_payload) |
| 186 | + |
| 187 | + if current_attempt >= max_attempts: |
| 188 | + raise Exception( |
| 189 | + "Error received when invoking AWS Lambda. See logs for further details." |
| 190 | + ) |
| 191 | + |
185 | 192 | return response_payload |
0 commit comments