From 20edee7f1a2293344827f20deee372381aa25021 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Fri, 26 Apr 2024 16:01:09 +0700 Subject: [PATCH] fix: ssr feature flags (#1119) ## Description Feature flags are broken on SSR due to this error ``` TypeError: fetch failed at Object.fetch (node:internal/deps/undici/undici:11731:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) { cause: RequestContentLengthMismatchError: Request body length does not match content-length header at write (node:internal/deps/undici/undici:8590:41) at _resume (node:internal/deps/undici/undici:8563:33) at resume (node:internal/deps/undici/undici:8459:7) at [dispatch] (node:internal/deps/undici/undici:7704:11) at Client.Intercept (node:internal/deps/undici/undici:7377:20) at Client.dispatch (node:internal/deps/undici/undici:6023:44) at [dispatch] (node:internal/deps/undici/undici:6254:32) at Pool.dispatch (node:internal/deps/undici/undici:6023:44) at [dispatch] (node:internal/deps/undici/undici:9343:27) at Agent.Intercept (node:internal/deps/undici/undici:7377:20) { code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' } } ``` I've removed content-length header since it isn't mandatory to my knowledge for get requests. ## Changes - Add fallback local flags when individual flag request fails - Add error logging - Remove `content-length` from headers being passed to Posthog --- packages/lib/universal/get-feature-flag.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/lib/universal/get-feature-flag.ts b/packages/lib/universal/get-feature-flag.ts index f4650f691..92f186ab3 100644 --- a/packages/lib/universal/get-feature-flag.ts +++ b/packages/lib/universal/get-feature-flag.ts @@ -17,6 +17,7 @@ export const getFlag = async ( options?: GetFlagOptions, ): Promise => { const requestHeaders = options?.requestHeaders ?? {}; + delete requestHeaders['content-length']; if (!isFeatureFlagEnabled()) { return LOCAL_FEATURE_FLAGS[flag] ?? true; @@ -25,7 +26,7 @@ export const getFlag = async ( const url = new URL(`${APP_BASE_URL()}/api/feature-flag/get`); url.searchParams.set('flag', flag); - const response = await fetch(url, { + return await fetch(url, { headers: { ...requestHeaders, }, @@ -35,9 +36,10 @@ export const getFlag = async ( }) .then(async (res) => res.json()) .then((res) => ZFeatureFlagValueSchema.parse(res)) - .catch(() => false); - - return response; + .catch((err) => { + console.error(err); + return LOCAL_FEATURE_FLAGS[flag] ?? false; + }); }; /** @@ -50,6 +52,7 @@ export const getAllFlags = async ( options?: GetFlagOptions, ): Promise> => { const requestHeaders = options?.requestHeaders ?? {}; + delete requestHeaders['content-length']; if (!isFeatureFlagEnabled()) { return LOCAL_FEATURE_FLAGS; @@ -67,7 +70,10 @@ export const getAllFlags = async ( }) .then(async (res) => res.json()) .then((res) => z.record(z.string(), ZFeatureFlagValueSchema).parse(res)) - .catch(() => LOCAL_FEATURE_FLAGS); + .catch((err) => { + console.error(err); + return LOCAL_FEATURE_FLAGS; + }); }; /** @@ -89,7 +95,10 @@ export const getAllAnonymousFlags = async (): Promise res.json()) .then((res) => z.record(z.string(), ZFeatureFlagValueSchema).parse(res)) - .catch(() => LOCAL_FEATURE_FLAGS); + .catch((err) => { + console.error(err); + return LOCAL_FEATURE_FLAGS; + }); }; interface GetFlagOptions {