Skip to content

Add support for remote config settings #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 13, 2025
Merged

Conversation

haacked
Copy link
Collaborator

@haacked haacked commented Feb 13, 2025

This PR also improves exception handling so that exceptions thrown from methods retrieving flags are unlikely. Error situations are logged instead.

This also changes FeatureFlag.Payload to be a JsonDocument.

@haacked haacked merged commit f7f0157 into main Feb 13, 2025
4 checks passed
@haacked haacked deleted the haacked/payload-refactorings branch February 13, 2025 18:53
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This PR adds remote config support and improves error handling in the PostHog .NET SDK, with significant changes to feature flag payload handling.

  • Changed FeatureFlag.Payload from string to JsonDocument for more robust JSON handling in /src/PostHog/Features/FeatureFlag.cs
  • Added new GetRemoteConfigPayloadAsync method in /src/PostHog/Api/PostHogApiClient.cs for retrieving remote config settings
  • Improved error handling by catching broader exceptions and adding structured logging throughout the codebase
  • Added UnauthorizedApiResult record in /src/PostHog/Api/ErrorApiResult.cs for better handling of 401 responses
  • Bumped version to 1.0.0-beta.6 in /Directory.Build.props to reflect new functionality

29 file(s) reviewed, 24 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines 341 to +346
/// <summary>
/// A filter that filters on a property.
/// </summary>
/// <param name="Type">The type of filter. Either "person" or "group".</param>
public record PropertyFilter(
FilterType Type,
string Key,
PropertyFilterValue Value,
ComparisonOperator? Operator = null,
[property: JsonPropertyName("group_type_index")]
int? GroupTypeIndex = null,
bool Negation = false) : Filter(Type)
/// <summary>
/// A filter that filters on a property.
/// </summary>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: Duplicate XML summary comment for PropertyFilter class

Suggested change
/// <summary>
/// A filter that filters on a property.
/// </summary>
/// <param name="Type">The type of filter. Either "person" or "group".</param>
public record PropertyFilter(
FilterType Type,
string Key,
PropertyFilterValue Value,
ComparisonOperator? Operator = null,
[property: JsonPropertyName("group_type_index")]
int? GroupTypeIndex = null,
bool Negation = false) : Filter(Type)
/// <summary>
/// A filter that filters on a property.
/// </summary>
/// <summary>
/// A filter that filters on a property.
/// </summary>

/// <param name="Type">The type of error.</param>
/// <param name="Code">The error code.</param>
/// <param name="Detail">Information about the error.</param>
/// <param name="Attr">???</param>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: The Attr parameter has unclear purpose and type. Consider documenting its purpose or removing if unused. Using object type is too permissive and could lead to runtime errors.

/// <param name="Code">The error code.</param>
/// <param name="Detail">Information about the error.</param>
/// <param name="Attr">???</param>
internal record UnauthorizedApiResult(string Type, string Code, string Detail, object Attr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider making properties nullable with string? since API responses may not always include all fields.

Comment on lines +9 to +10
/// <param name="Attr">???</param>
internal record UnauthorizedApiResult(string Type, string Code, string Detail, object Attr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: The XML documentation uses param tags incorrectly for record properties. Should use property tags instead: <property name="Type">The type of error.</property>

Comment on lines +153 to +154
{
_logger.LogErrorUnableToGetFeatureFlagsAndPayloads(e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: LogErrorUnableToGetFeatureFlagsAndPayloads is used but not defined in the logger extensions

var container = new TestContainer("fake-personal-api-key");
var client = container.Activate<PostHogClient>();

var result = await client.GetRemoteConfigPayloadAsync("non-existent-key");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: missing cancellation token parameter - should test behavior with cancellation

]
}
}
""";
var result = await JsonSerializerHelper.DeserializeFromCamelCaseJsonStringAsync<Filter>(json);

var propertyFilter = Assert.IsType<FilterSet>(result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: variable name 'propertyFilter' is misleading since it's actually a FilterSet

Suggested change
var propertyFilter = Assert.IsType<FilterSet>(result);
var filterSet = Assert.IsType<FilterSet>(result);

using System.Text.Json;
using System.Text.Json.Nodes;

public static class JsonAssert
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Class is missing XML documentation comments which are present on other public types in the codebase

Comment on lines +11 to +12
public static void Equal<T>(T expectedJson, JsonDocument? actualJson) =>
Equal(JsonSerializer.SerializeToDocument(expectedJson, typeof(T)), actualJson);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: No null check on expectedJson parameter. Could throw NullReferenceException when T is a reference type

Suggested change
public static void Equal<T>(T expectedJson, JsonDocument? actualJson) =>
Equal(JsonSerializer.SerializeToDocument(expectedJson, typeof(T)), actualJson);
public static void Equal<T>(T expectedJson, JsonDocument? actualJson)
{
if (expectedJson is null)
throw new ArgumentNullException(nameof(expectedJson));
Equal(JsonSerializer.SerializeToDocument(expectedJson, typeof(T)), actualJson);
}

Comment on lines +38 to +41
public static void Equal(
IReadOnlyDictionary<string, JsonDocument> expectedJson,
IReadOnlyDictionary<string, JsonDocument>? actualJson)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Method should validate that expectedJson is not null since it's not marked as nullable

Suggested change
public static void Equal(
IReadOnlyDictionary<string, JsonDocument> expectedJson,
IReadOnlyDictionary<string, JsonDocument>? actualJson)
{
public static void Equal(
IReadOnlyDictionary<string, JsonDocument> expectedJson,
IReadOnlyDictionary<string, JsonDocument>? actualJson)
{
ArgumentNullException.ThrowIfNull(expectedJson);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant