aws-lambda-dotnet: Amazon.Lambda.TestTool-6.0 serialization exception on Lambda's return value when using JSON serializer source generators

Description

An exception is thrown when trying to convert the result object of the function handler back to a stream in the Mock Lambda Test Tool on .Net 6 when using JSON source generators to serialize the result object.

This happens with types T for both T and Task<T> result types of the function handler, such as APIGatewayHttpApiV2ProxyResponse and Task<APIGatewayHttpApiV2ProxyResponse>, respectively.

An example of an exception thrown when the function handler’s result type is APIGatewayHttpApiV2ProxyResponse:

Amazon.Lambda.Serialization.SystemTextJson.JsonSerializerException: Error converting the response object of type System.Object from the Lambda function to JSON: No JsonTypeInfo registered in AWSLambdaTest.HttpApiJsonSerializerContext for type System.Object.

Reproduction Steps

From Visual Studio 2022, run the AWS .NET Core 6.0 Mock Lambda Test Tool with the following example code (a failing case for a non-async function handler). In Test Function select example request API Gateway V2 HTTP API and click Execute Function.

using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
using System.Text.Json.Serialization;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(SourceGeneratorLambdaJsonSerializer<AWSLambdaTest.HttpApiJsonSerializerContext>))]

namespace AWSLambdaTest;

[JsonSerializable(typeof(APIGatewayHttpApiV2ProxyRequest))]
[JsonSerializable(typeof(APIGatewayHttpApiV2ProxyResponse))]
public partial class HttpApiJsonSerializerContext : JsonSerializerContext
{
}

public partial class Function
{
    public APIGatewayHttpApiV2ProxyResponse Get(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context)
    {
        return new APIGatewayHttpApiV2ProxyResponse
        {
            Body = request.Body.ToUpper(),
            StatusCode = 200
        };
    }
}

Expected response:

{"statusCode":200,"body":"HELLO FROM LAMBDA","isBase64Encoded":false}

Actual response:

Amazon.Lambda.Serialization.SystemTextJson.JsonSerializerException: Error converting the response object of type System.Object from the Lambda function to JSON: No JsonTypeInfo registered in AWSLambdaTest.HttpApiJsonSerializerContext for type System.Object.
   at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Serialize[T](T response, Stream responseStream)
   at Amazon.Lambda.TestTool.Runtime.LambdaExecutor.ProcessReturnAsync(ExecutionRequest request, Object lambdaReturnObject) in C:\codebuild\tmp\output\src581676283\src\Tools\LambdaTestTool\src\Amazon.Lambda.TestTool\Runtime\LambdaExecutor.cs:line 162
   at Amazon.Lambda.TestTool.Runtime.LambdaExecutor.ExecuteAsync(ExecutionRequest request) in C:\codebuild\tmp\output\src581676283\src\Tools\LambdaTestTool\src\Amazon.Lambda.TestTool\Runtime\LambdaExecutor.cs:line 62
---------------- Inner 1 Exception ------------
Amazon.Lambda.Serialization.SystemTextJson.JsonSerializerException: No JsonTypeInfo registered in AWSLambdaTest.HttpApiJsonSerializerContext for type System.Object.
   at Amazon.Lambda.Serialization.SystemTextJson.SourceGeneratorLambdaJsonSerializer`1.InternalSerialize[T](Utf8JsonWriter writer, T response)
   at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Serialize[T](T response, Stream responseStream)

Logs

AWS .NET Core 6.0 Mock Lambda Test Tool (0.12.1)
Loaded local Lambda runtime from project output D:\src-test-2022\AWSLambdaTest\bin\Debug\net6.0
Found Lambda config file D:\src-test-2022\AWSLambdaTest\aws-lambda-tools-defaults.json
Environment running at http://localhost:5050

Environment

  • Build Version: Amazon.Lambda.TestTool 0.12.1
  • OS Info: Windows 10 Build 19044.1586
  • Build Environment: Visual Studio 2022 Version 17.1.2
  • Targeted .NET Platform: .Net 6 on Linux x64

Resolution

  • 👋 I can/would-like-to implement a fix for this problem myself
  • 👋 I think a have found a solution

It seems to be the case that the serialization implementation is trying to use a serializer supporting the static type of the result object (System.Object) in the Lambda TestTool (and not the dynamic/runtime type, like APIGatewayHttpApiV2ProxyResponse in the example above) to convert the result back to a stream (for which the source-generated serializer has no support).

A possible solution involves invoking the generic Serializer method with the correct runtime type as the type argument (instead of System.Object).


This is a 🐛 bug-report

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 15 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@normj – ran an initial test and all seems good – thanks for the quick response and fix!

I just pushed out version 0.12.5 with the fix.

Reproducible using customer’s code. Needs review with the team.