3
votes

I am attempting to use a AWS Lambda function in a Step Function. The Lambda Function works correctly when the it is tested individually and the json input is escaped. However when the input is passed to the lambda function through a step function, I am getting a JsonReaderException error. What am I doing wrong? Would the community know of a workaround for this issue?

lambda function:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization.Formatters.Binary;
using Amazon.Lambda.Core;
using Newtonsoft.Json.Linq;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
namespace AWSLambda1
{
    public class Function
    {
        public void PostsBasedOnOddOrEven(string input, ILambdaContext context)
        {
            var details = JObject.Parse(input);
            var postId = (int) details["id"];
            var oddOrEvenResult = (int) details["OddOrEvenPostsResult"];
        }
    }
}

Input to Lambda function from Step Function:

{
  "id": "1",
  "OddOrEvenPostsResult": 2
}

Input to Lambda function (which works through the Visual Studio Invoke):

"{ \"id\": \"1\", \"OddOrEvenPostsResult\": 2}"

Exception Stack Trace:

{
  "errorType": "JsonReaderException",
  "errorMessage": "Unexpected character encountered while parsing value: {. Path '', line 1, position 1.",
  "stackTrace": [
    "at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)",
    "at Newtonsoft.Json.JsonTextReader.ReadAsString()",
    "at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)",
    "at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)",
    "at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)",
    "at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)",
    "at Amazon.Lambda.Serialization.Json.JsonSerializer.Deserialize[T](Stream requestStream)",
    "at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
  ]
}

Lambda Function not working when it is part of Step Function

Lambda Function not working when it is part of Step Function

Lambda Function working when tested individually

Lambda Function working when tested individually

1
Which lines throws error? What is ILambdaContext and Posts ? Not possible to run whole program. - Gaurang Dave
The code you posted is fine. The exception occurs somewhere else. Some other part of the application tries to deserialize the input, which is a JSON object, as a JSON string. - Dmitry Egorov
I have added more details. Any help is appreciated. - Ajit Goel
Serialize your JSON to String before sending it to lambda function. - Dev Utkarsh

1 Answers

7
votes

Since your lambda function is expecting input to be a string, the framework tries to parse the input as though it's a string.

However, the input is actually a JSON object, not a string.

Therefore the parser will fail with an "unexpected character" error. The parser is expecting a " character which would indicate the start of a string.


So, here's how you can fix it:

  1. Declare a c# class which represents the input

    public class FunctionInput
    {
        public int id { get; set; }
        public int OddOrEvenPostsResult { get; set; }
    }
    
  2. Change your function signature to expect input of type FunctionInput

    public class Function
    {    
        public void PostsBasedOnOddOrEven(FunctionInput input, ILambdaContext context)
        {
            var postId = input.id;
            var oddOrEvenResult = input.OddOrEvenPostsResult;
        }
    }
    

Note: you don't need to parse the input yourself.