PostHog / posthog-js-lite

Reimplementation of posthog-js to be as light and modular as possible.
https://posthog.com/docs/libraries
MIT License
69 stars 36 forks source link

onlyEvaluateLocally is always producing empty array in Node.js 21.7 #228

Closed gajus closed 6 months ago

gajus commented 6 months ago

Bug description

/**
 * Evaluates the values for all flags for a single user
 */
public async getAllFlags({
  distinctId,
  onlyEvaluateLocally,
  personProperties,
}: {
  distinctId: string;
  onlyEvaluateLocally?: boolean;
  personProperties?: AnalyticsUserAttributes;
}): Promise<Record<string, boolean>> {
  if (!this.client) {
    this.log.warn('Posthog client is not initialized; returning empty flags');

    return {};
  }

  const featureFlags = (await this.client.getAllFlags(distinctId, {
    onlyEvaluateLocally,
    // @ts-expect-error incorrect library type
    personProperties,
  })) as Record<string, boolean>;

  if (Object.keys(featureFlags).length === 0) {
    // In all likelihood, this means that the PostHog feature flags are not set up correctly,
    // or there is something wrong with the PostHog client, e.g. we had a case where this
    // behaved correctly in Node.js 21.6 but not in 21.7.
    // We are logging this to Sentry so that it would trigger an alert.
    captureMessage('PostHog returned no feature flags', {
      extra: {
        distinctId,
        onlyEvaluateLocally,
        personProperties,
      },
    });

    this.log.warn('No feature flags were returned from Posthog');
  }

  return featureFlags;
}

This code path produces an empty object in Node.js 21.7, but works as expected in Node.js 21.6.

Replicated the same behavior with posthog-node@4.0.1 and posthog-node@3.2.0

How to reproduce

  1. Upgrade from Node.js 21.6 to 21.7

Related sub-libraries

Additional context

This issue is in relation to Contra account.

https://us.posthog.com/project/8910

marandaneto commented 6 months ago

@PostHog/team-feature-success

gajus commented 6 months ago

Same issue in Node.js v22

gajus commented 6 months ago

Looks like we are getting error:

Your personalApiKey is invalid. Are you sure you're not using your Project API key?

Since this is node.js version dependent, I am going to guess it is a bug in Node.js SDK.

neilkakkar commented 6 months ago

thanks for the report @gajus , I seemingly can't reproduce with either 21.7 or 22. Can you double check please the API keys are correct?

gajus commented 6 months ago
Screenshot 2024-05-16 at 10 19 39 AM

Just raised related product feedback, as there is no good way to validate if the key I have is valid.

gajus commented 6 months ago

Okay, no, it is def node version specific.

Generated new set of tokens.

Works with 21.6. Breaks with 21.7 and 22.

neilkakkar commented 6 months ago

weird, thanks 🤔 , let me try generating some new tokens too.

gajus commented 6 months ago

While I am not certain what's the cause of the issue, I was able to fix it by overriding the fetch client with got.

this.client = new PostHog(apiToken, {
  featureFlagsPollingInterval: 120_000,
  fetch: async (url, options) => {
    const response = await get(url, {
      body: options.body,
      headers: options.headers,
      method: options.method.toUpperCase() as 'GET',
      signal: options.signal,
    });

    return {
      json: async () => JSON.parse(response.body),
      status: response.statusCode,
      text: async () => response.body,
    };
  },
  fetchRetryCount: 0,
  personalApiKey,
  preloadFeatureFlags: false,
  requestTimeout: 5_000, // Measured in milliseconds. Defaults to 30_000 (30 seconds)
});
gajus commented 6 months ago

We tracked down the issue to be due to how @sentry/node v8 beta version instruments code in v21.6+.

Thank you for helping to troubleshoot.