vicfergar / HassClient

A Home Assistant client using Web Sockect API
GNU General Public License v3.0
18 stars 10 forks source link

System.ArgumentException: An item with the same key has already been added. (GetStatesAsync) #13

Closed alexbk66 closed 2 weeks ago

alexbk66 commented 11 months ago
System.ArgumentException: An item with the same key has already been added.
at: System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at: System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at: System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at: HassClient.Serialization.TupleSetToDictionaryConverter.ReadJson(JsonReader reader, Type objectType, Dictionary`2 existingValue, Boolean hasExistingValue, JsonSerializer serializer)

I added serialisation exception handler in JsonSerializerSettings to diagnose the problem - example of json causing the issue:

[["zwave_js","3636836764-1-0:4:4"],["zwave_js","3636836764-1"]]

Type: 'Device' path '[654].identifiers'

AllonisDave commented 11 months ago

I was able to resolve the issue by making the following change. I'm sure someone with a knowledge of Linq could do it a lot better.

    public override Dictionary<string, string> ReadJson(JsonReader reader, Type objectType, Dictionary<string, string> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var array = serializer.Deserialize<string[][]>(reader);

        if (array == null ||
            array.Length == 0)
        {
            return new Dictionary<string, string>();
        }

        // fixes System.ArgumentException: An item with the same key has already been added.
        Dictionary<string, string> dict = new Dictionary<string, string>();
        foreach (var item in array)
        {
           if (!dict.ContainsKey(item[0]))
           {
           dict.Add(item[0], item[1]);
           }
        }

        return dict;

        // return array.ToDictionary(x => x[0], x => x.Length > 1 ? x[1] : null);
    }
}
alexbk66 commented 11 months ago

I was able to resolve the issue by making the following change. I'm sure someone with a knowledge of Linq could do it a lot better.

That's not a fix - it's a workaround. I added exception handler instead (workaround as well).

vicfergar commented 2 weeks ago

@alexbk66 This issue should be fixed in the linked PR