Repository: getmoto/moto

Issue:
Mock lambda with body > 6Mb does not respond with 6Mb limit error

The sample lambda function should try to return a response that is too large:

```python
def lambda_handler(event, context):
    import sys

    x = ["xxx" for x in range(10 ** 6)]
    assert sys.getsizeof(x) > 6291556
    return {"statusCode": 200, "body": x}
```

When this is called in a moto lambda mock, it returns successfully.  It should return an error that the response exceeds the 6MB limit.

https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html notes that synchronous functions have limits:
- 6Mb for synchronous invoke payload and response
- the bytes value of `6291556` is from a live AWS Lambda error message

The error message is

```
'{\n "errorMessage": "Response payload size exceeded maximum allowed payload size (6291556 bytes).",\n "errorType": "Function.ResponseSizeTooLarge"\n}'
```

Or

```json
{
    "errorMessage": "Response payload size exceeded maximum allowed payload size (6291556 bytes).",
    "errorType": "Function.ResponseSizeTooLarge",
}
```



Discussion:

Resolving patch:
diff --git a/moto/awslambda/responses.py b/moto/awslambda/responses.py
--- a/moto/awslambda/responses.py
+++ b/moto/awslambda/responses.py
@@ -1,4 +1,5 @@
 import json
+import sys
 
 try:
     from urllib import unquote
@@ -207,6 +208,16 @@ def _invoke(self, request, full_url):
             function_name, qualifier, self.body, self.headers, response_headers
         )
         if payload:
+            if request.headers.get("X-Amz-Invocation-Type") != "Event":
+                if sys.getsizeof(payload) > 6000000:
+                    response_headers["Content-Length"] = "142"
+                    response_headers["x-amz-function-error"] = "Unhandled"
+                    error_dict = {
+                        "errorMessage": "Response payload size exceeded maximum allowed payload size (6291556 bytes).",
+                        "errorType": "Function.ResponseSizeTooLarge",
+                    }
+                    payload = json.dumps(error_dict).encode("utf-8")
+
             response_headers["content-type"] = "application/json"
             if request.headers.get("X-Amz-Invocation-Type") == "Event":
                 status_code = 202


Test patch:
diff --git a/tests/test_awslambda/test_lambda_invoke.py b/tests/test_awslambda/test_lambda_invoke.py
--- a/tests/test_awslambda/test_lambda_invoke.py
+++ b/tests/test_awslambda/test_lambda_invoke.py
@@ -19,6 +19,7 @@
     get_test_zip_file1,
     get_zip_with_multiple_files,
     get_test_zip_file2,
+    get_test_zip_largeresponse,
 )
 
 _lambda_region = "us-west-2"
@@ -294,3 +295,36 @@ def test_invoke_async_function(key):
     )
 
     success_result["Status"].should.equal(202)
+
+
+@pytest.mark.network
+@mock_lambda
+def test_invoke_function_large_response():
+    # AWS Lambda should only return bodies smaller than 6 MB
+    conn = boto3.client("lambda", _lambda_region)
+    fxn = conn.create_function(
+        FunctionName=str(uuid4())[0:6],
+        Runtime="python3.7",
+        Role=get_role_name(),
+        Handler="lambda_function.lambda_handler",
+        Code={"ZipFile": get_test_zip_largeresponse()},
+        Description="test lambda function",
+        Timeout=3,
+        MemorySize=128,
+        Publish=True,
+    )
+
+    resp = conn.invoke(FunctionName=fxn["FunctionArn"])
+    resp.should.have.key("FunctionError").equals("Unhandled")
+    payload = resp["Payload"].read().decode("utf-8")
+    payload = json.loads(payload)
+    payload.should.equal(
+        {
+            "errorMessage": "Response payload size exceeded maximum allowed payload size (6291556 bytes).",
+            "errorType": "Function.ResponseSizeTooLarge",
+        }
+    )
+
+    # Absolutely fine when invoking async
+    resp = conn.invoke(FunctionName=fxn["FunctionArn"], InvocationType="Event")
+    resp.shouldnt.have.key("FunctionError")
diff --git a/tests/test_awslambda/utilities.py b/tests/test_awslambda/utilities.py
--- a/tests/test_awslambda/utilities.py
+++ b/tests/test_awslambda/utilities.py
@@ -66,6 +66,15 @@ def lambda_handler(event, context):
     return _process_lambda(pfunc)
 
 
+def get_test_zip_largeresponse():
+    pfunc = """
+def lambda_handler(event, context):
+    x = ["xxx" for x in range(10 ** 6)]
+    return {"statusCode": 200, "body": x}
+"""
+    return _process_lambda(pfunc)
+
+
 def get_zip_with_multiple_files():
     pfunc = """
 from utilities import util_function