Error: An item with the same key has already been added. Key: stm, when I using Snowplow.tracker NuGet package

31 views Asked by At

Describe the bug

I am using the "snowplow.tracker" Nuget package in my dotnet core project. when I deployed my code on the server with the container, my server restarted every 2 minutes with the following error.

Occurred exception

Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: stm at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at Snowplow.Tracker.Endpoints.SnowplowHttpCollectorEndpoint.AddSendTimestamp(List1 payloadList) at Snowplow.Tracker.Endpoints.SnowplowHttpCollectorEndpoint.SendPostAsync(List1 itemList) at Snowplow.Tracker.Endpoints.SnowplowHttpCollectorEndpoint.Send(List`1 itemList) at Snowplow.Tracker.Emitters.AsyncEmitter.loop()

My code

public class SnowplowService : ISnowplowService
{
    private readonly SnowplowConfig _configuration;
    private readonly ILogger<SnowplowService> _logger;

    public SnowplowService(IOptions<SnowplowConfig> configuration,
        ILogger<SnowplowService> logger)
    {
        this._configuration = configuration.Value;
        this._logger = logger;
    }

    public async Task<SnowplowResponse> SendEvent(SnowplowRequest request)
    {
        var response = new SnowplowResponse();
        var tracker = Tracker.Instance;            
        var logger = new ConsoleLogger();
        var endpoint = new SnowplowHttpCollectorEndpoint
            (host: _configuration.BaseAddress, port: _configuration.Port, l: logger,
            method: Snowplow.Tracker.Endpoints.HttpMethod.POST, protocol: HttpProtocol.HTTP);

        try
        {
            var queue = new InMemoryBlockingQueue();
            var emitter = new AsyncEmitter(endpoint, queue, l: logger);
            var subject = new Subject().SetPlatform(Platform.Srv).SetLang(_configuration.Language);

            if (tracker.Started == false)
            {
                tracker.Start(
                    emitter: emitter,
                    subject: subject,
                    trackerNamespace: _configuration.TrackerNamespace,
                    appId: _configuration.AppId,
                    encodeBase64: false,
                    l: logger);
            }

            if (tracker.Started)
            {
                var dataKeyValues = new Dictionary<string, object>
                {
                    { "userId", request.UserId! },
                    { "eventName", request.EventName },
                    { "eventTime", request.EventTime },
                    { "eventData", Utility.ConvertToDictionaryObject(request: request.EventData) }
                };
                
                var eventKeyValues = new Dictionary<string, object>()
                {
                    { "vendor", _configuration.Vendor! },
                    { "model", request.SnowplowRequestName!},
                };

                var eventData = new SelfDescribingJson
                    ($"iglu:{_configuration.Vendor}/{request.SnowplowRequestName!}/jsonschema/1-0-0", dataKeyValues);

                var requestItem = new List<IContext>();

                var context = new GenericContext()
                    .SetSchema($"iglu:com.vendor/meta/jsonschema/1-0-0")
                    .AddDict(eventKeyValues)
                    .Build();

                requestItem.Add(item: context);

                var trackingItem =
                    new SelfDescribing()
                    .SetEventData(eventData: eventData)
                    .SetCustomContext(customContexts: requestItem)
                    .Build();
                
                tracker.Track(newEvent: trackingItem);
            }

            response = new SnowplowResponse(true, "");
        }
        catch (Exception ex)
        {
            response = new SnowplowResponse(false, ex.Message);
        }

        return response;
    }
}

        internal static Dictionary<string, object> ConvertToDictionaryObject<T>(T request) where T : class
        {
            var result = new Dictionary<string, object>();

            var properties = request.GetType().GetProperties();

            foreach (var item in properties)
            {
                var key = item.Name.ToLower().Trim();

                var value = item.GetValue(request);

                if (result.ContainsKey(key) == false)
                    result.Add(key: key, value: value!);
            }

            return result;
        }
0

There are 0 answers