diff --git a/src/PostHog.AspNetCore/README.md b/src/PostHog.AspNetCore/README.md index ad52fcd..0eae1e5 100644 --- a/src/PostHog.AspNetCore/README.md +++ b/src/PostHog.AspNetCore/README.md @@ -65,6 +65,18 @@ The available options are: > When that number is reached, the client will start dropping older events. `MaxBatchSize` ensures that the `/batch` > request doesn't get too large. +### Local Evaluation + +If you want to evaluate feature flags locally, you'll need to provide a personal API key for the PostHog API. + +For local development, you can set the `PostHog:PersonalApiKey` setting in your user secrets: + +```bash +$ dotnet user-secrets set PostHog:PersonalApiKey YOUR_PERSONAL_API_KEY +``` + +For production, we recommend using a secrets manager or environment variables to set the `PostHog:PersonalApiKey` setting. + ## Docs More detailed docs for using this library can be found at [PostHog Docs for the .NET Client SDK](https://posthog.com/docs/libraries/dotnet). diff --git a/src/PostHog/Api/PostHogApiClient.cs b/src/PostHog/Api/PostHogApiClient.cs index 06b260c..bab5a65 100644 --- a/src/PostHog/Api/PostHogApiClient.cs +++ b/src/PostHog/Api/PostHogApiClient.cs @@ -151,7 +151,7 @@ public async Task SendEventAsync( try { return await GetAuthenticatedResponseAsync( - $"/api/feature_flag/local_evaluation/?token={options.ProjectApiKey}&send_cohorts", + $"/api/feature_flag/local_evaluation/?send_cohorts", cancellationToken); } catch (ApiException e) when (e.ErrorType is "quota_limited") diff --git a/src/PostHog/Library/HttpClientExtensions.cs b/src/PostHog/Library/HttpClientExtensions.cs index 06890f3..49370c3 100644 --- a/src/PostHog/Library/HttpClientExtensions.cs +++ b/src/PostHog/Library/HttpClientExtensions.cs @@ -45,11 +45,17 @@ public static async Task EnsureSuccessfulApiCall( this HttpResponseMessage response, CancellationToken cancellationToken) { - // TODO: Is there any error status codes that we should allow the exception to propagate here? if (response.IsSuccessStatusCode) { return; } + + if (response.StatusCode == HttpStatusCode.NotFound) + { + // Allow 404 exception to propagate up. + response.EnsureSuccessStatusCode(); + } + var (error, exception) = await ReadApiErrorResultAsync(); throw response.StatusCode switch diff --git a/tests/TestLibrary/Fakes/FakeHttpMessageHandlerExtensions.cs b/tests/TestLibrary/Fakes/FakeHttpMessageHandlerExtensions.cs index 8128ba5..8264cf9 100644 --- a/tests/TestLibrary/Fakes/FakeHttpMessageHandlerExtensions.cs +++ b/tests/TestLibrary/Fakes/FakeHttpMessageHandlerExtensions.cs @@ -73,15 +73,9 @@ public static FakeHttpMessageHandler.RequestHandler AddLocalEvaluationResponse( public static FakeHttpMessageHandler.RequestHandler AddLocalEvaluationResponse( this FakeHttpMessageHandler handler, - LocalEvaluationApiResult responseBody) - => handler.AddLocalEvaluationResponse("fake-project-api-key", responseBody); - - public static FakeHttpMessageHandler.RequestHandler AddLocalEvaluationResponse( - this FakeHttpMessageHandler handler, - string projectApiKey, LocalEvaluationApiResult responseBody) => handler.AddResponse( - new Uri($"https://us.i.posthog.com/api/feature_flag/local_evaluation/?token={projectApiKey}&send_cohorts"), + new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?send_cohorts"), HttpMethod.Get, responseBody: responseBody); diff --git a/tests/UnitTests/Features/FeatureFlagsTests.cs b/tests/UnitTests/Features/FeatureFlagsTests.cs index c5bf706..491d31b 100644 --- a/tests/UnitTests/Features/FeatureFlagsTests.cs +++ b/tests/UnitTests/Features/FeatureFlagsTests.cs @@ -3228,7 +3228,7 @@ public async Task ReturnsEmptyDictionaryWhenPersonalApiKeyIncorrect() FeatureFlagPayloads = new Dictionary(), }); container.FakeHttpMessageHandler.AddResponse( - new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?token=fake-project-api-key&send_cohorts"), + new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?send_cohorts"), HttpMethod.Get, new HttpResponseMessage(HttpStatusCode.Unauthorized) { @@ -3384,7 +3384,7 @@ public async Task ReturnsEmptyDictionaryWhenLocalEvaluationQuotaExceeded() // When local evaluation is quota limited, we do not want to fallback to /decide. var decideHandler = container.FakeHttpMessageHandler.AddDecideResponseException(new InvalidOperationException()); container.FakeHttpMessageHandler.AddResponse( - new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?token=fake-project-api-key&send_cohorts"), + new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?send_cohorts"), HttpMethod.Get, new HttpResponseMessage(HttpStatusCode.PaymentRequired) { @@ -3416,7 +3416,7 @@ public async Task ReturnsFalseWhenSingleFlagLocalEvaluationRequestQuotaExceeded( var container = new TestContainer("fake-personal-api-key"); var decideHandler = container.FakeHttpMessageHandler.AddDecideResponseException(new InvalidOperationException()); container.FakeHttpMessageHandler.AddResponse( - new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?token=fake-project-api-key&send_cohorts"), + new Uri("https://us.i.posthog.com/api/feature_flag/local_evaluation/?send_cohorts"), HttpMethod.Get, new HttpResponseMessage(HttpStatusCode.PaymentRequired) {