Unleash / unleash-client-dotnet

Unleash client SDK for .NET
Apache License 2.0
77 stars 39 forks source link

We see a lot "The `appName` property is required. It was not present on the data you sent." #207

Closed PeterDierckx78 closed 5 months ago

PeterDierckx78 commented 5 months ago

Describe the bug Each time the unleash client sends its metrics we see the error: "The appName property is required. It was not present on the data you sent." This is due to fact that the body is empty in the Post request call of the client/metrics call.

To Reproduce Steps to reproduce the behavior:

  1. Configure unleash with appName, projectId, apiKey, url, we use the System.Text.Json.JsonSerializer
  2. Create an Unleashclient with FetchToggleInterval set to i.e. 20 seconds.
  3. Call the client.IsEnabled("any flag", context)
  4. Wait for next fetch interval
  5. See error

Expected behavior We should see no errors.

Actual behavior We see the error: The appName property is required. It was not present on the data you sent. on each sendMetrics interval.

Desktop (please complete the following information):

Additional context After some debugging I see that the seek position of the memoryStream that is used to fill the appName, InstanceId, Bucket is not reset to the start of the stream. So when you pass it to the request.Content it will start reading at the end of the stream, so the body is always empty.

If you add the following line before passing the stream into the request.Content you will jump to the start of the stream and so your request body will contain the expected info. memoryStream.Seek(0, SeekOrigin.Begin);

So this is an easy fix.

So in the file UnleashApiClient.cs in function SendMetrics: add this seek function as shown below:

        ...
        using (metrics.StopCollectingMetrics(out var bucket))
        {
            jsonSerializer.Serialize(memoryStream, new ClientMetrics
            {
                AppName = clientRequestHeaders.AppName,
                InstanceId = clientRequestHeaders.InstanceTag,
                Bucket = bucket
            });
        }
        memoryStream.Seek(0, SeekOrigin.Begin); //<=== HERE
kwasniew commented 5 months ago

If you're not using newtonsoft serializer then we recommend to follow those steps: https://github.com/Unleash/unleash-client-dotnet?tab=readme-ov-file#json-serialization. It recommends to handle this in the user space (setting stream position in the serialize method)

PeterDierckx78 commented 5 months ago

Thanks. We could indeed fix this issue in our Serializer by setting position to 0 after the serializing operation.