Skip to content

DynamoDB events have milliseconds, not seconds, in their timestamps which crashes deserialization #839

Closed
@cdegroot

Description

@cdegroot

Description

I'm creating a lambda to process DynamoDB events streamed through Kinesis, which means they're wrapped in base64, etcetera. During processing I pull them out and then deserialize them to DynamoDBv2 records:

            var serializer = new Amazon.Lambda.Serialization.Json.JsonSerializer();
            var dynamoEvent = serializer.Deserialize<Amazon.DynamoDBv2.Model.Record>(BaseObserver.GenerateStreamFromString(dynamoData));

Reproduction Steps

This gist: https://gist.github.com/cdegroot/6e8e1957d9d08a595b3918dce3e16d84. Note that all I did was to add a couple of zeros to the test event.

Logs

Stacktrace:

  X TestDynamoParsing [8ms]
  Error Message:
   Test method Canary.EventStore.Tests.BaseObserverTests.TestDynamoParsing threw exception: 
Amazon.Lambda.Serialization.Json.JsonSerializerException: Error converting the Lambda event JSON payload to type Amazon.DynamoDBv2.Model.Record: Value to add was out of range. (Parameter 'value') ---> System.ArgumentOutOfRangeException: Value to add was out of range. (Parameter 'value')                                                                                    
  Stack Trace:
      at System.DateTime.Add(Double value, Int32 scale)
   at System.DateTime.AddSeconds(Double value)
   at Amazon.Lambda.Serialization.Json.JsonNumberToDateTimeDataConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   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(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
   at Amazon.Lambda.Serialization.Json.JsonSerializer.Deserialize[T](Stream requestStream)
--- End of inner exception stack trace ---
    at Amazon.Lambda.Serialization.Json.JsonSerializer.Deserialize[T](Stream requestStream

Environment

  • Build Version: 1.2.0
  • OS Info: Ubuntu 20.10
  • Build Environment: Terminal dotnet test etc.
  • Targeted .NET Platform: 3.1

Resolution

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

I can look later, will just kill the last three digits with a regex for now, but the usual fix is to take a cut-off value (100000000000 - somewhere in the 6th millenium) and if it's above, interpret as millisecs, if not, as secs.

Of course, the proper fix is to make DynamoDB emit always one or the other :)


This is a 🐛 bug-report

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.module/lambda-client-libp2This is a standard priority issuequeuedresponse-requestedWaiting on additional info and feedback. Will move to close soon in 7 days.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions