From e5ead50a3d0f74b7e0cacf6e3f8a61ba25ff1d51 Mon Sep 17 00:00:00 2001 From: vimzh Date: Sun, 24 May 2026 11:46:19 +0530 Subject: [PATCH] fix(tweet-preview): guard JSON.parse to avoid crashing on malformed tweet data TweetPreview was passing the result of `JSON.parse(data)` straight into `enrichTweet` whenever `data` was a string. If a document's stored tweet metadata was ever a non-JSON string, truncated JSON, or `"null"` / `"123"`, the unguarded parse threw and crashed the React tree rendering the document modal or memory card. Extract the parse into a `parseTweetData` helper that returns `null` when the input is missing, fails to parse, or doesn't resolve to an object. TweetPreview now renders nothing in those cases instead of crashing. Also widen the prop type from `Tweet` to `Tweet | string` to reflect the runtime input both call sites already pass. --- .../components/document-cards/tweet-preview.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/web/components/document-cards/tweet-preview.tsx b/apps/web/components/document-cards/tweet-preview.tsx index 807ba5b9..894d4d12 100644 --- a/apps/web/components/document-cards/tweet-preview.tsx +++ b/apps/web/components/document-cards/tweet-preview.tsx @@ -117,14 +117,26 @@ function CustomTweetMedia({ ) } +function parseTweetData(data: Tweet | string): Tweet | null { + if (!data) return null + if (typeof data !== "string") return data + try { + const parsed = JSON.parse(data) + return parsed && typeof parsed === "object" ? (parsed as Tweet) : null + } catch { + return null + } +} + export function TweetPreview({ data, noBgColor, }: { - data: Tweet + data: Tweet | string noBgColor?: boolean }) { - const parsedTweet = typeof data === "string" ? JSON.parse(data) : data + const parsedTweet = parseTweetData(data) + if (!parsedTweet) return null const tweet = enrichTweet(parsedTweet) return (