From 8b77159abe0dbb4c371b3b3796a228fec962f2db Mon Sep 17 00:00:00 2001 From: Eugene Fox Date: Wed, 7 May 2025 00:03:43 +0300 Subject: [PATCH] hotfix: wrapped analytics into try/catch to prevent failing on firefox --- entrypoints/background.ts | 4 ++-- entrypoints/sidepanel/components/EditDialog.tsx | 5 +++-- .../layouts/collections/CollectionListView.tsx | 3 ++- .../layouts/collections/messages/CtaMessage.tsx | 7 ++++--- .../sidepanel/layouts/header/MoreButton.tsx | 5 +++-- features/analytics/index.ts | 1 + features/analytics/utils/track.ts | 11 +++++++++++ features/analytics/utils/trackError.ts | 17 ++++++++++++----- features/v3welcome/components/WelcomeDialog.tsx | 3 ++- utils/saveTabsToCollection.ts | 5 +++-- 10 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 features/analytics/utils/track.ts diff --git a/entrypoints/background.ts b/entrypoints/background.ts index 266321f..be8a02d 100644 --- a/entrypoints/background.ts +++ b/entrypoints/background.ts @@ -1,4 +1,4 @@ -import { trackError } from "@/features/analytics"; +import { track, trackError } from "@/features/analytics"; import { collectionCount, getCollections, saveCollections } from "@/features/collectionStorage"; import { migrateStorage } from "@/features/migration"; import { showWelcomeDialog } from "@/features/v3welcome/utils/showWelcomeDialog"; @@ -31,7 +31,7 @@ export default defineBackground(() => browser.runtime.onInstalled.addListener(async ({ reason, previousVersion }) => { logger("onInstalled", reason, previousVersion); - analytics.track("extension_installed", { reason, previousVersion: previousVersion ?? "none" }); + track("extension_installed", { reason, previousVersion: previousVersion ?? "none" }); const previousMajor: number = previousVersion ? parseInt(previousVersion.split(".")[0]) : 0; diff --git a/entrypoints/sidepanel/components/EditDialog.tsx b/entrypoints/sidepanel/components/EditDialog.tsx index ba28478..a863891 100644 --- a/entrypoints/sidepanel/components/EditDialog.tsx +++ b/entrypoints/sidepanel/components/EditDialog.tsx @@ -1,4 +1,5 @@ import { getCollectionTitle } from "@/entrypoints/sidepanel/utils/getCollectionTitle"; +import { track } from "@/features/analytics"; import { useGroupColors } from "@/hooks/useGroupColors"; import { CollectionItem, GroupItem } from "@/models/CollectionModels"; import * as fui from "@fluentui/react-components"; @@ -27,9 +28,9 @@ export default function EditDialog(props: GroupEditDialogProps): ReactElement const handleSave = () => { if (props.type === "collection" ? props.collection !== null : props.group !== null) - analytics.track("item_edited", { type: props.type }); + track("item_edited", { type: props.type }); else - analytics.track("item_created", { type: props.type }); + track("item_created", { type: props.type }); if (props.type === "collection") props.onSave({ diff --git a/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx b/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx index 4471c4c..4b91f47 100644 --- a/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx +++ b/entrypoints/sidepanel/layouts/collections/CollectionListView.tsx @@ -5,6 +5,7 @@ import CloudIssueMessages from "@/entrypoints/sidepanel/layouts/collections/mess import CtaMessage from "@/entrypoints/sidepanel/layouts/collections/messages/CtaMessage"; import filterCollections, { CollectionFilterType } from "@/entrypoints/sidepanel/utils/filterCollections"; import sortCollections from "@/entrypoints/sidepanel/utils/sortCollections"; +import { track } from "@/features/analytics"; import useSettings from "@/hooks/useSettings"; import { CollectionItem } from "@/models/CollectionModels"; import { DndContext, DragEndEvent, DragOverlay, DragStartEvent, MouseSensor, TouchSensor, useSensor, useSensors } from "@dnd-kit/core"; @@ -65,7 +66,7 @@ export default function CollectionListView(): ReactElement if (sortMode !== "custom") setSortMode("custom"); - analytics.track("used_drag_and_drop"); + track("used_drag_and_drop"); } }; diff --git a/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx b/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx index 0afb3fd..73afa51 100644 --- a/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx +++ b/entrypoints/sidepanel/layouts/collections/messages/CtaMessage.tsx @@ -1,5 +1,6 @@ import { BuyMeACoffee20Regular } from "@/assets/BuyMeACoffee20"; import { buyMeACoffeeLink, storeLink } from "@/data/links"; +import { track } from "@/features/analytics"; import { useBmcStyles } from "@/hooks/useBmcStyles"; import extLink from "@/utils/extLink"; import { Button, Link, MessageBar, MessageBarActions, MessageBarBody, MessageBarProps, MessageBarTitle } from "@fluentui/react-components"; @@ -29,9 +30,9 @@ export default function CtaMessage(props: MessageBarProps): ReactElement setCounter(counter); if (counter === -1) - analytics.track("bmc_clicked"); + track("bmc_clicked"); else - analytics.track("cta_dismissed"); + track("cta_dismissed"); }; if (counter < 50) @@ -41,7 +42,7 @@ export default function CtaMessage(props: MessageBarProps): ReactElement } { ...props }> { i18n.t("cta_message.title") } - { i18n.t("cta_message.message") } analytics.track("feedback_clicked") }>{ i18n.t("cta_message.feedback") } + { i18n.t("cta_message.message") } track("feedback_clicked") }>{ i18n.t("cta_message.feedback") } - } { ...extLink(buyMeACoffeeLink) } onClick={ () => analytics.track("feedback_clicked") }> + } { ...extLink(buyMeACoffeeLink) } onClick={ () => track("feedback_clicked") }> { i18n.t("common.cta.sponsor") } - } { ...extLink(storeLink) } onClick={ () => analytics.track("bmc_clicked") }> + } { ...extLink(storeLink) } onClick={ () => track("bmc_clicked") }> { i18n.t("common.cta.feedback") } } { ...extLink(githubLinks.release) } > diff --git a/features/analytics/index.ts b/features/analytics/index.ts index 9bb71e6..301debd 100644 --- a/features/analytics/index.ts +++ b/features/analytics/index.ts @@ -1,2 +1,3 @@ export { default as userPropertiesStorage } from "./utils/userPropertiesStorage"; export { default as trackError } from "./utils/trackError"; +export { default as track } from "./utils/track"; diff --git a/features/analytics/utils/track.ts b/features/analytics/utils/track.ts new file mode 100644 index 0000000..2162843 --- /dev/null +++ b/features/analytics/utils/track.ts @@ -0,0 +1,11 @@ +export default function track(eventName: string, eventProperties?: Record): void +{ + try + { + analytics.track(eventName, eventProperties); + } + catch (ex) + { + console.error("Failed to send analytics event", ex); + } +} diff --git a/features/analytics/utils/trackError.ts b/features/analytics/utils/trackError.ts index 840a291..004378c 100644 --- a/features/analytics/utils/trackError.ts +++ b/features/analytics/utils/trackError.ts @@ -1,8 +1,15 @@ export default function trackError(name: string, error: Error): void { - analytics.track(name, { - name: error.name, - message: error.message, - stack: error.stack ?? "no_stack" - }); + try + { + analytics.track(name, { + name: error.name, + message: error.message, + stack: error.stack ?? "no_stack" + }); + } + catch (ex) + { + console.error("Failed to send error report", ex); + } } diff --git a/features/v3welcome/components/WelcomeDialog.tsx b/features/v3welcome/components/WelcomeDialog.tsx index 3085564..963d1fa 100644 --- a/features/v3welcome/components/WelcomeDialog.tsx +++ b/features/v3welcome/components/WelcomeDialog.tsx @@ -1,5 +1,6 @@ import { useTheme } from "@/contexts/ThemeProvider"; import { v3blogPost } from "@/data/links"; +import { track } from "@/features/analytics"; import extLink from "@/utils/extLink"; import * as fui from "@fluentui/react-components"; @@ -41,7 +42,7 @@ export default function WelcomeDialog(): React.ReactElement analytics.track("visit_blog_button_click") } + onClick={ () => track("visit_blog_button_click") } > { i18n.t("features.v3welcome.actions.visit_blog") } diff --git a/utils/saveTabsToCollection.ts b/utils/saveTabsToCollection.ts index e155cdd..c92877b 100644 --- a/utils/saveTabsToCollection.ts +++ b/utils/saveTabsToCollection.ts @@ -1,7 +1,8 @@ +import { track } from "@/features/analytics"; import { CollectionItem, GroupItem } from "@/models/CollectionModels"; import { Tabs } from "wxt/browser"; -import { settings } from "./settings"; import sendNotification from "./sendNotification"; +import { settings } from "./settings"; export default async function saveTabsToCollection(closeTabs: boolean): Promise { @@ -24,7 +25,7 @@ export default async function saveTabsToCollection(closeTabs: boolean): Promise< if (closeTabs) await browser.tabs.remove(tabsToClose.map(i => i.id!)); - analytics.track(closeTabs ? "set_aside" : "save"); + track(closeTabs ? "set_aside" : "save"); return collection; }