-
Notifications
You must be signed in to change notification settings - Fork 494
Description
Describe the issue
This issue is as much documenting something I found for future reference, as well as suggesting this might need a change in the documentation.
I started off here to create a brand new lambda fronted by API gateway. This all seems fine but I'm not a top level statements guy so I chose to go with the good old Program class with a static Main method.
When I was done developing I uploaded a zip to lambda to do a quick check if everything worked. I tested it with this payload:
{
"resource": "/{proxy+}",
"path": "/",
"httpMethod": "GET",
"requestContext": {
"accountId": "123456789012",
"resourceId": "123456",
"stage": "prod",
"requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
"requestTime": "09/Apr/2015:12:34:56 +0000",
"requestTimeEpoch": 1428582896000,
"path": "/prod/",
"resourcePath": "/{proxy+}",
"httpMethod": "GET",
"apiId": "1234567890",
"protocol": "HTTP/1.1"
}
}but was given this exception:
{
"errorType": "JsonSerializerException",
"errorMessage": "Error converting the Lambda event JSON payload to type System.String[]: The JSON value could not be converted to System.String[]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.",
"stackTrace": [
"at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Deserialize[T](Stream requestStream)",
"at lambda_method1(Closure, Stream, ILambdaContext, Stream)",
"at Amazon.Lambda.RuntimeSupport.HandlerWrapper.<>c__DisplayClass8_0.<GetHandlerWrapper>b__0(InvocationRequest invocation) in /src/Repo/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/HandlerWrapper.cs:line 68",
"at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.<>c__DisplayClass26_0.<<InvokeOnceAsync>b__0>d.MoveNext() in /src/Repo/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs:line 357"
],
"cause": {
"errorType": "JsonException",
"errorMessage": "The JSON value could not be converted to System.String[]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.",
"stackTrace": [
"at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)",
"at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)",
"at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)",
"at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)",
"at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)",
"at System.Text.Json.JsonSerializer.Deserialize[TValue](ReadOnlySpan`1 utf8Json, JsonSerializerOptions options)",
"at Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer.InternalDeserialize[T](Byte[] utf8Json)",
"at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Deserialize[T](Stream requestStream)"
]
}
}After a few hours of digging I figured out that it was because my Main method had a signature like Main(string[] args). The runtime is trying to bind the request object to the string[] args which fails as it's not at all a string array. If you were to pass a string array first, the function would be initialized and subsequent requests would work for as long as that instance of the lambda remained up.
I'm familiar with the setup where the handler typically has the events object, so I could see how this happens. I'm not sure a code fix is needed, it might just be a gotcha which is now documented here at least. It might be worth calling this out in the documentation though that when NOT using top level statements you want a main method that does not have any arguments.
Trivial example here, this one fails as described above on initialization:
https://github.com/hvanbakel/LambdaTopLevelArgs/blob/master/LambdaTopLevelArgs.Main/Program.cs
This one just works as expected:
https://github.com/hvanbakel/LambdaTopLevelArgs/blob/master/LambdaTopLevelArgs.TopLevel/Program.cs