aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.5k stars 1.17k forks source link

When local, API Gateway is in error when body containing just one integer (while lambda alone is in success) #1124

Closed cyrilhamidechi closed 5 years ago

cyrilhamidechi commented 5 years ago

Description

First thank you for your work! 🎉

As stated in the title, on local testing, API Gateway is in error for body containing just one integer while lambda is in success.

Steps to reproduce

template.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An example SAM template for Lambda Safe Deployments.

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:

  heyFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hey/
      Handler: app.handler
      Runtime: nodejs8.10
      Events:
        returnS3Buckets:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hey
            Method: get

hey/app.js:

"use strict";

exports.handler = (event, context, callback) => {
  callback(null, {
    statusCode: 200,
    body: 42
  });
};
sam build && sam local start-api --skip-pull-image --debug

Observed result

2019-04-15 18:28:43 Building resource 'heyFunction'
2019-04-15 18:28:43 Running NodejsNpmBuilder:NpmPack
2019-04-15 18:28:44 Running NodejsNpmBuilder:CopyNpmrc
2019-04-15 18:28:44 Running NodejsNpmBuilder:CopySource
2019-04-15 18:28:44 Running NodejsNpmBuilder:NpmInstall
2019-04-15 18:28:45 Running NodejsNpmBuilder:CleanUpNpmrc

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Package: sam package --s3-bucket <yourbucket>

2019-04-15 18:28:46 Using SAM Template at /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/template.yaml
2019-04-15 18:28:46 Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2019-04-15 18:28:46 Changing event name from before-call.apigateway to before-call.api-gateway
2019-04-15 18:28:46 Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2019-04-15 18:28:46 Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2019-04-15 18:28:46 Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2019-04-15 18:28:46 Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
2019-04-15 18:28:46 Changing event name from docs.*.autoscaling.CreateLaunchConfiguration.complete-section to docs.*.auto-scaling.CreateLaunchConfiguration.complete-section
2019-04-15 18:28:46 Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask
2019-04-15 18:28:46 Changing event name from docs.*.logs.CreateExportTask.complete-section to docs.*.cloudwatch-logs.CreateExportTask.complete-section
2019-04-15 18:28:46 Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search
2019-04-15 18:28:46 Changing event name from docs.*.cloudsearchdomain.Search.complete-section to docs.*.cloudsearch-domain.Search.complete-section
2019-04-15 18:28:46 Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2019-04-15 18:28:46 Changing event name from before-call.apigateway to before-call.api-gateway
2019-04-15 18:28:46 Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2019-04-15 18:28:46 Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2019-04-15 18:28:46 Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2019-04-15 18:28:46 Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
2019-04-15 18:28:46 Changing event name from docs.*.autoscaling.CreateLaunchConfiguration.complete-section to docs.*.auto-scaling.CreateLaunchConfiguration.complete-section
2019-04-15 18:28:46 Changing event name from before-parameter-build.logs.CreateExportTask to before-parameter-build.cloudwatch-logs.CreateExportTask
2019-04-15 18:28:46 Changing event name from docs.*.logs.CreateExportTask.complete-section to docs.*.cloudwatch-logs.CreateExportTask.complete-section
2019-04-15 18:28:46 Changing event name from before-parameter-build.cloudsearchdomain.Search to before-parameter-build.cloudsearch-domain.Search
2019-04-15 18:28:46 Changing event name from docs.*.cloudsearchdomain.Search.complete-section to docs.*.cloudsearch-domain.Search.complete-section
2019-04-15 18:28:46 local start-api command is called
2019-04-15 18:28:46 No Parameters detected in the template
2019-04-15 18:28:46 2 resources found in the template
2019-04-15 18:28:46 Found Serverless function with name='heyFunction' and CodeUri='heyFunction'
2019-04-15 18:28:46 Trying paths: ['/Users/cyril/.docker/config.json', '/Users/cyril/.dockercfg']
2019-04-15 18:28:46 Found file at path: /Users/cyril/.docker/config.json
2019-04-15 18:28:46 Couldn't find auth-related section ; attempting to interpret as auth-only file
2019-04-15 18:28:46 Config entry for key stackOrchestrator is not auth config
2019-04-15 18:28:46 http://localhost:None "GET /v1.35/_ping HTTP/1.1" 200 2
2019-04-15 18:28:46 No Parameters detected in the template
2019-04-15 18:28:46 2 resources found in the template
2019-04-15 18:28:46 Found '1' API Events in Serverless function with name 'heyFunction'
2019-04-15 18:28:46 Detected Inline Swagger definition
2019-04-15 18:28:46 Lambda function integration not found in Swagger document at path='/hey' method='get'
2019-04-15 18:28:46 Found '0' APIs in resource 'ServerlessRestApi'
2019-04-15 18:28:46 Removed duplicates from '0' Explicit APIs and '1' Implicit APIs to produce '1' APIs
2019-04-15 18:28:46 1 APIs found in the template
2019-04-15 18:28:46 Looking for credentials via: env
2019-04-15 18:28:46 Looking for credentials via: assume-role
2019-04-15 18:28:46 Looking for credentials via: shared-credentials-file
2019-04-15 18:28:46 Found credentials in shared credentials file: ~/.aws/credentials
2019-04-15 18:28:46 Loading JSON file: /usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/botocore/data/endpoints.json
2019-04-15 18:28:46 Event choose-service-name: calling handler <function handle_service_name_alias at 0x11135eae8>
2019-04-15 18:28:46 Loading JSON file: /usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/botocore/data/lambda/2015-03-31/service-2.json
2019-04-15 18:28:46 Event creating-client-class.lambda: calling handler <function add_generate_presigned_url at 0x111323620>
2019-04-15 18:28:46 The s3 config key is not a dictionary type, ignoring its value of: None
2019-04-15 18:28:46 Setting lambda timeout as (60, 60)
2019-04-15 18:28:46 Loading JSON file: /usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/botocore/data/_retry.json
2019-04-15 18:28:46 Registering retry handlers for service: lambda
2019-04-15 18:28:46 Trying paths: ['/Users/cyril/.docker/config.json', '/Users/cyril/.dockercfg']
2019-04-15 18:28:46 Found file at path: /Users/cyril/.docker/config.json
2019-04-15 18:28:46 Couldn't find auth-related section ; attempting to interpret as auth-only file
2019-04-15 18:28:46 Config entry for key stackOrchestrator is not auth config
2019-04-15 18:28:46 Mounting heyFunction at http://127.0.0.1:3000/hey [GET]
2019-04-15 18:28:46 You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2019-04-15 18:28:46 Localhost server is starting up. Multi-threading = True
2019-04-15 18:28:46  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

Then calling in browser URL http://localhost:3000/hey

2019-04-15 18:29:46 Constructed String representation of Event to invoke Lambda. Event: {"httpMethod": "GET", "body": null, "resource": "/hey", "requestContext": {"resourceId": "123456", "apiId": "1234567890", "resourcePath": "/hey", "httpMethod": "GET", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "accountId": "123456789012", "stage": "prod", "identity": {"apiKey": null, "userArn": null, "cognitoAuthenticationType": null, "caller": null, "userAgent": "Custom User Agent String", "user": null, "cognitoIdentityPoolId": null, "cognitoAuthenticationProvider": null, "sourceIp": "127.0.0.1", "accountId": null}, "extendedRequestId": null, "path": "/hey"}, "queryStringParameters": null, "headers": {"Host": "localhost:3000", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "Pragma": "no-cache", "Cache-Control": "no-cache", "X-Forwarded-Proto": "http", "X-Forwarded-Port": "3000"}, "pathParameters": null, "stageVariables": null, "path": "/hey", "isBase64Encoded": false}
2019-04-15 18:29:46 Found one Lambda function with name 'heyFunction'
2019-04-15 18:29:46 Invoking app.handler (nodejs8.10)
2019-04-15 18:29:46 No environment variables found for function 'heyFunction'
2019-04-15 18:29:46 Environment variables overrides data is standard format
2019-04-15 18:29:46 Loading AWS credentials from session with profile 'default'
2019-04-15 18:29:46 Resolving code path. Cwd=/Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build, CodeUri=heyFunction
2019-04-15 18:29:46 Resolved absolute path to code is /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/heyFunction
2019-04-15 18:29:46 Code /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/heyFunction is not a zip/jar file
2019-04-15 18:29:46 Skipping building an image since no layers were defined
2019-04-15 18:29:46 Trying paths: ['/Users/cyril/.docker/config.json', '/Users/cyril/.dockercfg']
2019-04-15 18:29:46 Found file at path: /Users/cyril/.docker/config.json
2019-04-15 18:29:46 Couldn't find auth-related section ; attempting to interpret as auth-only file
2019-04-15 18:29:46 Config entry for key stackOrchestrator is not auth config
2019-04-15 18:29:46 http://localhost:None "GET /v1.35/images/lambci/lambda:nodejs8.10/json HTTP/1.1" 200 None
2019-04-15 18:29:46 Requested to skip pulling images ...

2019-04-15 18:29:46 Mounting /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/heyFunction as /var/task:ro inside runtime container
2019-04-15 18:29:46 http://localhost:None "POST /v1.35/containers/create HTTP/1.1" 201 90
2019-04-15 18:29:46 http://localhost:None "GET /v1.35/containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90/json HTTP/1.1" 200 None
2019-04-15 18:29:46 http://localhost:None "GET /v1.35/containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90/json HTTP/1.1" 200 None
2019-04-15 18:29:47 http://localhost:None "POST /v1.35/containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90/start HTTP/1.1" 204 0
2019-04-15 18:29:47 Starting a timer for 3 seconds for function 'heyFunction'
2019-04-15 18:29:47 http://localhost:None "GET /v1.35/containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90/json HTTP/1.1" 200 None
2019-04-15 18:29:47 http://localhost:None "POST /containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90/attach?stdout=1&stderr=1&logs=1&stream=1&stdin=0 HTTP/1.1" 101 0
START RequestId: dd1011aa-75b2-117e-3d7d-6071158dd3d3 Version: $LATEST
END RequestId: dd1011aa-75b2-117e-3d7d-6071158dd3d3
REPORT RequestId: dd1011aa-75b2-117e-3d7d-6071158dd3d3  Duration: 10.50 ms  Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 30 MB  
2019-04-15 18:29:47 http://localhost:None "GET /v1.35/containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90/json HTTP/1.1" 200 None
2019-04-15 18:29:48 http://localhost:None "DELETE /v1.35/containers/28c3af9cf13dd2a10c591995ae56099bb187aa6c680f5950177838046f8c9f90?v=False&link=False&force=True HTTP/1.1" 204 0
2019-04-15 18:29:48 No Content-Type given. Defaulting to 'application/json'.
2019-04-15 18:29:48 127.0.0.1 - - [15/Apr/2019 18:29:48] "GET /hey HTTP/1.1" 500 -
2019-04-15 18:29:48 Error on request:
Traceback (most recent call last):
  File "/usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/werkzeug/serving.py", line 302, in run_wsgi
    execute(self.server.app)
  File "/usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/werkzeug/serving.py", line 292, in execute
    for data in application_iter:
  File "/usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/werkzeug/wsgi.py", line 507, in __next__
    return self._next()
  File "/usr/local/Cellar/aws-sam-cli/0.14.2/libexec/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py", line 45, in _iter_encoded
    for item in iterable:
TypeError: 'int' object is not iterable
2019-04-15 18:29:48 127.0.0.1 - - [15/Apr/2019 18:29:48] "GET /favicon.ico HTTP/1.1" 403 -

Same code perfectly works when directly calling the lambde (through the invoke feature)

Expected result

By just converting integer into string, e.g. + "" it works. It should work with or with strong conversion. This updated code

"use strict";

exports.handler = (event, context, callback) => {
  callback(null, {
    statusCode: 200,
    body: 42 + ""
  });
};

gives when calling the URL

2019-04-15 18:32:15 Constructed String representation of Event to invoke Lambda. Event: {"httpMethod": "GET", "body": null, "resource": "/hey", "requestContext": {"resourceId": "123456", "apiId": "1234567890", "resourcePath": "/hey", "httpMethod": "GET", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "accountId": "123456789012", "stage": "prod", "identity": {"apiKey": null, "userArn": null, "cognitoAuthenticationType": null, "caller": null, "userAgent": "Custom User Agent String", "user": null, "cognitoIdentityPoolId": null, "cognitoAuthenticationProvider": null, "sourceIp": "127.0.0.1", "accountId": null}, "extendedRequestId": null, "path": "/hey"}, "queryStringParameters": null, "headers": {"Host": "localhost:3000", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "Pragma": "no-cache", "Cache-Control": "no-cache", "X-Forwarded-Proto": "http", "X-Forwarded-Port": "3000"}, "pathParameters": null, "stageVariables": null, "path": "/hey", "isBase64Encoded": false}
2019-04-15 18:32:15 Found one Lambda function with name 'heyFunction'
2019-04-15 18:32:15 Invoking app.handler (nodejs8.10)
2019-04-15 18:32:15 No environment variables found for function 'heyFunction'
2019-04-15 18:32:15 Environment variables overrides data is standard format
2019-04-15 18:32:15 Loading AWS credentials from session with profile 'default'
2019-04-15 18:32:15 Resolving code path. Cwd=/Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build, CodeUri=heyFunction
2019-04-15 18:32:15 Resolved absolute path to code is /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/heyFunction
2019-04-15 18:32:15 Code /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/heyFunction is not a zip/jar file
2019-04-15 18:32:15 Skipping building an image since no layers were defined
2019-04-15 18:32:15 Trying paths: ['/Users/cyril/.docker/config.json', '/Users/cyril/.dockercfg']
2019-04-15 18:32:15 Found file at path: /Users/cyril/.docker/config.json
2019-04-15 18:32:15 Couldn't find auth-related section ; attempting to interpret as auth-only file
2019-04-15 18:32:15 Config entry for key stackOrchestrator is not auth config
2019-04-15 18:32:15 http://localhost:None "GET /v1.35/images/lambci/lambda:nodejs8.10/json HTTP/1.1" 200 None
2019-04-15 18:32:15 Requested to skip pulling images ...

2019-04-15 18:32:15 Mounting /Users/cyril/Documents/Dev/Perso/lambda-ci/.aws-sam/build/heyFunction as /var/task:ro inside runtime container
2019-04-15 18:32:15 http://localhost:None "POST /v1.35/containers/create HTTP/1.1" 201 90
2019-04-15 18:32:15 http://localhost:None "GET /v1.35/containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41/json HTTP/1.1" 200 None
2019-04-15 18:32:15 http://localhost:None "GET /v1.35/containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41/json HTTP/1.1" 200 None
2019-04-15 18:32:16 http://localhost:None "POST /v1.35/containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41/start HTTP/1.1" 204 0
2019-04-15 18:32:16 Starting a timer for 3 seconds for function 'heyFunction'
2019-04-15 18:32:16 http://localhost:None "GET /v1.35/containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41/json HTTP/1.1" 200 None
2019-04-15 18:32:16 http://localhost:None "POST /containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41/attach?stdout=1&stderr=1&logs=1&stream=1&stdin=0 HTTP/1.1" 101 0
START RequestId: 8289a27a-a9f4-1f9c-6329-7b3292c11f94 Version: $LATEST
END RequestId: 8289a27a-a9f4-1f9c-6329-7b3292c11f94
REPORT RequestId: 8289a27a-a9f4-1f9c-6329-7b3292c11f94  Duration: 11.83 ms  Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 30 MB  
2019-04-15 18:32:17 http://localhost:None "GET /v1.35/containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41/json HTTP/1.1" 200 None
2019-04-15 18:32:17 http://localhost:None "DELETE /v1.35/containers/f2a54776309341ae5018c59c99f1f6172d114283ec17c9627f8c395ea4483f41?v=False&link=False&force=True HTTP/1.1" 204 0
2019-04-15 18:32:17 No Content-Type given. Defaulting to 'application/json'.
2019-04-15 18:32:17 127.0.0.1 - - [15/Apr/2019 18:32:17] "GET /hey HTTP/1.1" 200 -

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: Mac OSX Mojave 10.14.4
  2. sam --version: SAM CLI, version 0.14.2
jfuss commented 5 years ago

Release in v0.21.0.

Closing