From e7a3f3408e0e6e59766fdaa5811c730b0976a73e Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Thu, 16 Mar 2017 22:00:57 -0400 Subject: [PATCH] Add Lambda header for invoking error. Closes #770. --- moto/awslambda/models.py | 12 ++++++---- tests/test_awslambda/test_lambda.py | 37 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py index 477537d10..a3b1f715f 100644 --- a/moto/awslambda/models.py +++ b/moto/awslambda/models.py @@ -138,6 +138,7 @@ class LambdaFunction(BaseModel): except Exception as ex: print("Exception %s", ex) + errored = False try: original_stdout = sys.stdout original_stderr = sys.stderr @@ -152,26 +153,29 @@ class LambdaFunction(BaseModel): if exec_err: result = "\n".join([exec_out.strip(), self.convert(exec_err)]) except Exception as ex: + errored = True result = '%s\n\n\nException %s' % (mycode, ex) finally: codeErr.close() codeOut.close() sys.stdout = original_stdout sys.stderr = original_stderr - return self.convert(result) + return self.convert(result), errored def invoke(self, body, request_headers, response_headers): payload = dict() # Get the invocation type: - r = self._invoke_lambda(code=self.code, event=body) + res, errored = self._invoke_lambda(code=self.code, event=body) if request_headers.get("x-amz-invocation-type") == "RequestResponse": - encoded = base64.b64encode(r.encode('utf-8')) + encoded = base64.b64encode(res.encode('utf-8')) response_headers["x-amz-log-result"] = encoded.decode('utf-8') payload['result'] = response_headers["x-amz-log-result"] - result = r.encode('utf-8') + result = res.encode('utf-8') else: result = json.dumps(payload) + if errored: + response_headers['x-amz-function-error'] = "Handled" return result diff --git a/tests/test_awslambda/test_lambda.py b/tests/test_awslambda/test_lambda.py index d967c8bad..007516f56 100644 --- a/tests/test_awslambda/test_lambda.py +++ b/tests/test_awslambda/test_lambda.py @@ -432,3 +432,40 @@ def test_list_create_list_get_delete_list(): conn.delete_function(FunctionName='testFunction') conn.list_functions()['Functions'].should.have.length_of(0) + + +@mock_lambda +def test_invoke_lambda_error(): + lambda_fx = """ + def lambda_handler(event, context): + raise Exception('failsauce') + """ + zip_output = io.BytesIO() + zip_file = zipfile.ZipFile(zip_output, 'w', zipfile.ZIP_DEFLATED) + zip_file.writestr('lambda_function.zip', lambda_fx) + zip_file.close() + zip_output.seek(0) + + client = boto3.client('lambda', region_name='us-east-1') + client.create_function( + FunctionName='test-lambda-fx', + Runtime='python2.7', + Role='test-iam-role', + Handler='lambda_function.lambda_handler', + Description='test lambda function', + Timeout=3, + MemorySize=128, + Publish=True, + Code={ + 'ZipFile': zip_output.read() + }, + ) + + result = client.invoke( + FunctionName='test-lambda-fx', + InvocationType='RequestResponse', + LogType='Tail' + ) + + assert 'FunctionError' in result + assert result['FunctionError'] == 'Handled'