Vonage/vonage-dotnet-sdk

StartTime is not nullable in class Answered (EventWebHook)

MarcusKohnert opened this issue ยท 6 comments

Describe the bug
I'm using the EventBase.ParseEvent method to parse the received webhook events.

Expected behaviour:
The method is able to parse an Answered event send by Vonage.

{
    "start_time": null,
    "headers": {
        "[redacted]": "[redacted]"
    },
    "rate": null,
    "from": "[redacted]",
    "to": "[redacted]",
    "uuid": "c8061992c89a65e3790bfa0aaca6f069",
    "conversation_uuid": "CON-5a0cdebb-0f35-45a4-9b38-a99f9d12d6d7",
    "status": "answered",
    "direction": "inbound",
    "network": null,
    "timestamp": "2024-01-25T12:16:32.319Z"
}

Actual behaviour:
EventBase.ParseEvent throws an exception because start_time is null and StartTime is of type DateTime (which is not nullable).

StackTrace

Newtonsoft.Json.JsonSerializationException
  HResult=0x80131500
  Message=Error converting value {null} to type 'System.DateTime'. Path 'start_time', line 1, position 18.
  Source=Newtonsoft.Json
  StackTrace:
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   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.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Vonage.Voice.EventWebhooks.EventBase.DeserializeStatus(String json, JProperty statusProperty)
   at Vonage.Voice.EventWebhooks.EventBase.ParseEvent(String json)

  This exception was originally thrown at this call stack:
    System.Convert.ChangeType(object, System.Type, System.IFormatProvider)
    Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(Newtonsoft.Json.JsonReader, object, System.Globalization.CultureInfo, Newtonsoft.Json.Serialization.JsonContract, System.Type)

Inner Exception 1:
InvalidCastException: Null object cannot be converted to a value type.

Environment:

  • .NET Runtime: .NET7
  • SDK Version 6.15.0
Tr00d commented

Hi @MarcusKohnert,

Thanks for raising that one. I'll have a look asap

Tr00d commented

Hi @MarcusKohnert,

FYI the issue is fixed - the PR is linked.
Unfortunately, this change can be considered a breaking change as I'm altering the signature of a public object. Normally, I should wait for the next major version (v7.0.0), but I was expecting that later this year.
I'm considering pushing this one through anyway, given the current class is unstable. I'll let you know the outcome

Unblocked myself with the following workaround:

EventBase eventBase;
try
{
    eventBase = EventBase.ParseEvent(json);
}
catch (JsonSerializationException) // workaround https://github.com/Vonage/vonage-dotnet-sdk/issues/567
{
    var callStatusEvent = JsonConvert.DeserializeObject<CallStatusEvent>(json, VonageSerialization.SerializerSettings)!;
    eventBase = new Answered
    {
        From             = callStatusEvent.From,
        Uuid             = callStatusEvent.Uuid,
        ConversationUuid = callStatusEvent.ConversationUuid,
        To               = callStatusEvent.To,
        Direction        = callStatusEvent.Direction,
        Status           = callStatusEvent.Status,
        DetailString     = callStatusEvent.DetailString,
        StartTime        = DateTime.Now,
        TimeStamp        = callStatusEvent.TimeStamp
    };
}
Tr00d commented

I'm sorry you had to go down that route ๐Ÿ˜…

Hi @MarcusKohnert,

I wanted to share some feedback. This breaking change is available in the latest version v7.0.0-alpha.
Being an alpha, the package is still subject to potential problems. I do expect a final version very soon.

Hi,

v7.0.0 is finally out, and this problem has been addressed.

Don't hesitate to share some feedback ๐Ÿ˜„