8

Getting the JSON sent to a Lambda Function when Deserialization Fails

 2 years ago
source link: https://nodogmablog.bryanhogan.net/2023/02/getting-the-json-sent-to-a-lambda-function-when-deserialization-fails/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Getting the JSON sent to a Lambda Function when Deserialization Fails

When working with Lambda functions that handle events raised by other services (AWS or third party), it can sometimes be difficult to work out what the right model is to use as the input to the function.

I hit this problem recently when using a Lambda function to handle an event sent via EventBridge from another service, but the technique will work with JSON sent from any source.

My function handler looked like this:

public void FunctionHandler(CloudWatchEvent<SomeServiceStatusChange> someServiceStatusChange, ILambdaContext context)
{
    // work with someServiceStatusChange...
}

I thought I had the correct model in my function, but I got the following errors in the CloudWatch logs:

Error converting the Lambda event JSON payload to type...
System.Text.Json.JsonException: The JSON value could not be converted to...

I made a minor change to my model but still got the same error.

At this point, it was clear that my model didn’t match the JSON the function was receiving. Deserialization was not going to work until I fixed the model. But to fix the model, I needed to know what the JSON looked like.

How to output the raw JSON

To see the raw JSON that the function handler receives, I changed the parameter type to the type Stream. .NET Lambda functions support the Stream type without any serialization/deserialization.

After receiving the stream, I read it to a string, and log it to CloudWatch. No more deserialization errors and I can see the raw JSON.

public void FunctionHandler(Stream someServiceStatusChange, ILambdaContext context)
{
    StreamReader reader = new StreamReader(someServiceStatusChange);
    string json = reader.ReadToEnd();
    context.Logger.LogInformation($"someServiceStatusChange:{json}");
}

I invoked the service that uses EventBridge to send the event to the Lambda function, then I opened the logs of the Lambda function in CloudWatch.

The raw JSON is now visible in the logs. I can use that to create the correct model.

2023-02-17T11:01:311Z   a4ea2b10-b5ba-4a12-b182-df7a12bbede1    info    input:
{
    "version": "0",
    "id": "45a19a57-ea9c-4d9d-9e01-4465f9840e84",
    "detail-type": "Some Service State Change",
    "source": "someservice",
    "account": "694977046108",
    "time": "2023-02-17T11:01:51Z",
    "region": "us-east-1",
    "resources": [],
    "detail": {
        "SomeServiceJobName": "8591b623-207f-4537-9dbe-8f1aeb28a258",
        "SomeServiceJobStatus": "COMPLETED"
    }
}

Now it’s a simple matter of updating the model to match the JSON.


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK