Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SystemTextJson.DefaultLambdaJsonSerializer throws a NullReferenceException when null is returned if LAMBDA_NET_SERIALIZER_DEBUG is enabled #1328

Closed
crose-varde opened this issue Sep 30, 2022 · 5 comments
Labels
bug This issue is a bug. module/lambda-client-lib p2 This is a standard priority issue queued

Comments

@crose-varde
Copy link

crose-varde commented Sep 30, 2022

Describe the bug

When using Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer (or any class derived from AbstractLambdaJsonSerializer), if the LAMBDA_NET_SERIALIZER_DEBUG environment variable is set to true, and null is returned from the function handler, the debugging code invoked during serialization of the response causes a NullReferenceException to be thrown.

Expected Behavior

No exception should be thrown.

Current Behavior

If you're using Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer (or any class derived from Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer) and you return null from the function handler with the LAMBDA_NET_SERIALIZER_DEBUG environment variable set to true you get this stack trace:

fail	Amazon.Lambda.Serialization.SystemTextJson.JsonSerializerException: Error converting the response object of type System.Object from the Lambda function to JSON: Object reference not set to an instance of an object.
---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Object.GetType()
at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Serialize[T](T response, Stream responseStream)
--- End of inner exception stack trace ---
at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Serialize[T](T response, Stream responseStream)
at lambda_method1(Closure , Stream , ILambdaContext , Stream )
at Amazon.Lambda.RuntimeSupport.Bootstrap.UserCodeLoader.Invoke(Stream lambdaData, ILambdaContext lambdaContext, Stream outStream) in /src/Repo/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs:line 145
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 56
at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.InvokeOnceAsync(CancellationToken cancellationToken) in /src/Repo/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs:line 176

Reproduction Steps

  1. Set the LAMBDA_NET_SERIALIZER_DEBUG environment variable to true.
  2. Use Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer for serialization:
[assembly:LambdaSerializer(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer)]
  1. Execute this function handler:
public object? FunctionHandler(string _input)
{
    return null;
}

Possible Solution

The problem is in the serialization debugging code that is executed when LAMBDA_NET_SERIALIZER_DEBUG is set to true. The specific error is in AbstractLambdaJsonSerializer, when it tries to get the name of the response type to log to the console. When the response is null, then response.GetType() throws the NRE. If the debug flag isn't set, then this code path is never executed, and there's no exception.

Additional Information/Context

Returning null is sometimes necessary when implementing an AppSync direct resolver, which is why I ran into this.

AWS .NET SDK and/or Package version used

AWSSDK.Core 3.7.13.3
Amazon.Lambda.Core 2.1.0
Amazon.Lambda.Serialization.SystemTextJson 2.3.0

Targeted .NET Platform

.NET 6

Operating System and version

whatever lambda is running i guess (x86_64 arch)

@crose-varde crose-varde added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 30, 2022
@ashishdhingra
Copy link
Contributor

@crose-varde Thanks for opening the bug report. Just out of curiosity, could you please share your use case where you needed to use LAMBDA_NET_SERIALIZER_DEBUG.

Thanks,
Ashish

@ashishdhingra ashishdhingra added B needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. labels Sep 30, 2022
@ashishdhingra
Copy link
Contributor

The issue is reproducible in actual AWS Lambda environment (not in Mock Lambda test tool), only when null is returned in function call and LAMBDA_NET_SERIALIZER_DEBUG is set to true in environment variables.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   timestamp   |                                                                                                                                          message                                                                                                                                           |
|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1664908764759 | START RequestId: cd29070a-8c31-441a-a2ac-918a80858e9d Version: $LATEST                                                                                                                                                                                                                     |
| 1664908764954 | 2022-10-04T18:39:24.897Z cd29070a-8c31-441a-a2ac-918a80858e9d info Lambda Deserialize System.String: "Hello World"                                                                                                                                                                         |
| 1664908765155 | 2022-10-04T18:39:25.155Z cd29070a-8c31-441a-a2ac-918a80858e9d fail Amazon.Lambda.Serialization.SystemTextJson.JsonSerializerException: Error converting the response object of type System.Object from the Lambda function to JSON: Object reference not set to an instance of an object.  |
| 1664908765155 | ---> System.NullReferenceException: Object reference not set to an instance of an object.                                                                                                                                                                                                  |
| 1664908765155 | at System.Object.GetType()                                                                                                                                                                                                                                                                 |
| 1664908765155 | at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Serialize[T](T response, Stream responseStream)                                                                                                                                                                 |
| 1664908765155 | --- End of inner exception stack trace ---                                                                                                                                                                                                                                                 |
| 1664908765155 | at Amazon.Lambda.Serialization.SystemTextJson.AbstractLambdaJsonSerializer.Serialize[T](T response, Stream responseStream)                                                                                                                                                                 |
| 1664908765155 | at Amazon.Lambda.RuntimeSupport.Bootstrap.UserCodeLoader.Invoke(Stream lambdaData, ILambdaContext lambdaContext, Stream outStream) in /src/Repo/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/UserCodeLoader.cs:line 145                                                            |
| 1664908765155 | 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 56                                                                      |
| 1664908765155 | at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.InvokeOnceAsync(CancellationToken cancellationToken) in /src/Repo/Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs:line 176                                                                                         |
| 1664908765274 | END RequestId: cd29070a-8c31-441a-a2ac-918a80858e9d                                                                                                                                                                                                                                        |
| 1664908765274 | REPORT RequestId: cd29070a-8c31-441a-a2ac-918a80858e9d Duration: 498.29 ms Billed Duration: 499 ms Memory Size: 256 MB Max Memory Used: 65 MB Init Duration: 221.30 ms                                                                                                                     |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

@crose-varde Although I agree that the null values should be handled, could you please share the use case where null would be returned, instead of handling it in application logic.

Thanks,
Ashish

@ashishdhingra ashishdhingra added needs-review and removed needs-reproduction This issue needs reproduction. labels Oct 4, 2022
@ashishdhingra ashishdhingra added queued p2 This is a standard priority issue and removed B labels Nov 1, 2022
@crose-varde
Copy link
Author

@ashishdhingra consider this partial GraphQL schema:

Query {
    tryGetWidget(id: ID!): Widget
}

The tryGetWidget query property returns an optional Widget object. If there's no widget for a given ID, null is returned, rather than emitting an error of some sort. (I think this is a reasonable way to design a schema, and GraphQL fully supports it.)

A direct lambda resolver that handles this will have to return null in some cases.

@normj
Copy link
Member

normj commented Oct 23, 2024

Version 2.4.4 of Amazon.Lambda.Serialization.SystemTextJson has been released that fixes the debug null pointer exception. Thanks for letting us know.

@normj normj closed this as completed Oct 23, 2024
Copy link
Contributor

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. module/lambda-client-lib p2 This is a standard priority issue queued
Projects
None yet
Development

No branches or pull requests

3 participants