Skip to content

fix/sentry-logging#442

Merged
IAmKio merged 4 commits intostagingfrom
fix/sentry-logging
Oct 24, 2025
Merged

fix/sentry-logging#442
IAmKio merged 4 commits intostagingfrom
fix/sentry-logging

Conversation

@IAmKio
Copy link
Collaborator

@IAmKio IAmKio commented Oct 24, 2025

Description

  • Reduced Sentry logging by around 90% - logging removals may seem overzealous for now but we will slowly re-introduce logging once we can establish that the quota issue has been resolved

How Has This Been Tested?

  • Locally

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • Chores
    • Simplified error reporting to focus on critical issues only
    • Disabled performance monitoring and replay tracking
    • Significantly reduced telemetry data collection and breadcrumb logging across the exchange flow
    • Removed non-essential user-interaction and diagnostic logs; preserved user-facing behavior and error messaging
    • Tightened event payloads and lowered sampling to minimize data sent to external monitoring services

@IAmKio IAmKio requested a review from RanaBug October 24, 2025 12:51
@IAmKio IAmKio self-assigned this Oct 24, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 24, 2025

Walkthrough

This PR removes most Sentry logging helpers and breadcrumb calls across the exchange app and app-wide init, consolidating telemetry to a single error-focused helper (logExchangeError), disabling tracing/replay, and removing dynamic wallet address context from logs.

Changes

Cohort / File(s) Summary
Sentry Utilities Refactor
src/apps/the-exchange/utils/sentry.ts, src/apps/the-exchange/SENTRY_LOGGING.md
Removed many logging helpers (logExchangeEvent, logOperation, logSwapOperation, logUserInteraction, addExchangeBreadcrumb, startExchangeTransaction, etc.). Simplified logExchangeError and made useWalletAddressForLogging return static 'unknown_wallet_address'. Public API surface reduced.
Exchange Components — Logging Removal
src/apps/the-exchange/components/CardsSwap/CardsSwap.tsx, src/apps/the-exchange/components/EnterAmount/EnterAmount.tsx, src/apps/the-exchange/components/SelectToken/SelectToken.tsx, src/apps/the-exchange/components/SwapSummary/SwapSummary.tsx
Removed imports and usage of transaction-kit wallet data and all breadcrumb/user-interaction logging calls; preserved component logic and signatures but removed telemetry side effects.
Exchange Action & Tests
src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx, src/apps/the-exchange/components/ExchangeAction/test/ExchangeAction.test.tsx
Removed startExchangeTransaction and other tracing/log calls; replaced instrumentation with error-only logging via logExchangeError. Removed Sentry mock stubs in tests.
Exchange Hooks & App Init
src/apps/the-exchange/hooks/useOffer.tsx, src/apps/the-exchange/index.tsx
Dropped wallet address tracking and tracing calls in fee-estimation and initialization flows; replaced multi-field logging calls with logExchangeError on errors only.
App Sentry Config & Auth Context
src/main.tsx, src/containers/Main.tsx
Removed browser tracing and replay integrations; lowered tracesSampleRate and disabled replays. beforeSend now sanitizes and trims events (breadcrumbs, contexts, extra). Authentication breadcrumb/context population reduced and made error-focused.
Send Modal Logging Removal
src/components/BottomMenuModal/SendModal/SendModalBottomButtons.tsx
Removed Sentry imports, context setup, and breadcrumb calls; UI and button behavior unchanged aside from telemetry removal.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • vignesha22
  • RanaBug

Poem

🐇✨ I hopped through code and nibbled traces,
Breadcrumbs vanished from quiet places.
Now only errors tug my sleeve,
I’m small, I’m calm — I’ll softly grieve.
Carrots saved for the next release.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The pull request title "fix/sentry-logging" is related to the changeset but lacks specificity and clarity. While it correctly identifies that changes involve Sentry logging, the title is too vague to convey the primary change to someone scanning commit history. The actual change is a significant reduction in logging (90%) to address a quota issue, but the title does not communicate this scope, intent, or the nature of the fix. It reads more like a generic branch name than a descriptive commit message.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed The pull request description follows the required template structure and includes all major sections: a clear description explaining the 90% logging reduction and quota context, a testing section noting local testing, and properly marked change types indicating a non-breaking bug fix. While the testing section is brief, it provides sufficient information for this type of change. The description clearly explains the purpose and intent of the changes without leaving critical information missing.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/sentry-logging

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 24, 2025

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2544471
Status: ✅  Deploy successful!
Preview URL: https://786a27bc.x-e62.pages.dev
Branch Preview URL: https://fix-sentry-logging.x-e62.pages.dev

View logs

@IAmKio IAmKio marked this pull request as ready for review October 24, 2025 12:56
@IAmKio IAmKio requested a review from vignesha22 October 24, 2025 13:17
@github-actions github-actions bot temporarily deployed to Preview (fix/sentry-logging) October 24, 2025 13:49 Inactive
@github-actions github-actions bot temporarily deployed to Preview (fix/sentry-logging) October 24, 2025 13:58 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/apps/the-exchange/components/EnterAmount/EnterAmount.tsx (1)

136-147: Align error payload with logExchangeError allowlist; current fields are dropped

logExchangeError only persists operation, swapToken, receiveToken, amount. Passing params and walletAddress here is ignored, losing useful diagnostics.

Update payload to recognized keys (and include chainIds succinctly). Example:

-      logExchangeError(
-        e,
-        {
-          operation: 'get_best_offer',
-          params,
-          walletAddress,
-        },
-        {
-          component: 'EnterAmount',
-          method: 'getOffer',
-        }
-      );
+      logExchangeError(
+        e instanceof Error ? e : String(e),
+        {
+          operation: 'get_best_offer',
+          swapToken: swapToken?.symbol,
+          receiveToken: receiveToken?.symbol,
+          amount: amountSwap,
+          fromChainId: chainNameToChainIdTokensData(swapToken?.blockchain) ?? undefined,
+          toChainId: chainNameToChainIdTokensData(receiveToken?.blockchain) ?? undefined,
+          walletAddress,
+        },
+        { component: 'EnterAmount', method: 'getOffer' }
+      );

Also see util-side enhancement below to pick up walletAddress and chainId.

src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx (1)

244-258: Fix payload key: use amount instead of amountSwap

logExchangeError whitelists amount; amountSwap won’t be captured.

       logExchangeError(
         error instanceof Error ? error : String(error),
         {
           operation: 'exchange_click',
           swapToken: swapToken?.symbol,
           receiveToken: receiveToken?.symbol,
-          amountSwap,
+          amount: amountSwap,
           walletAddress,
         },
         {
           component: 'ExchangeAction',
           method: 'onClickToExchange',
         }
       );
src/apps/the-exchange/utils/sentry.ts (1)

22-33: Support walletAddress and additional exchange context in Sentry logging

The current implementation discards critical data that call sites actively provide. All four call sites pass walletAddress, one passes chainId, and one passes amountSwap—but the current whitelist drops them. Adopt the proposed changes to capture this data.

 export const logExchangeError = (
   error: Error | string,
   extra?: Record<string, unknown>,
   tags?: Record<string, string>
 ) => {
-  const walletAddress = fallbackWalletAddressForLogging();
+  const ex = (extra ?? {}) as Record<string, unknown>;
+  const walletAddress =
+    (typeof ex.walletAddress === 'string' && ex.walletAddress) ||
+    fallbackWalletAddressForLogging();

   Sentry.withScope((scope) => {
     scope.setLevel('error');
     scope.setTag('wallet_address', walletAddress);
     scope.setTag('app_module', 'the-exchange');
     scope.setTag('error_type', 'exchange_error');

@@
-    // Only include essential error data
-    if (extra) {
-      const essentialData = {
-        operation: extra.operation,
-        swapToken: extra.swapToken,
-        receiveToken: extra.receiveToken,
-        amount: extra.amount,
-      };
-      scope.setExtra('exchange_error_data', essentialData);
-    }
+    // Only include essential error data (support common aliases)
+    if (extra) {
+      const essentialData = {
+        operation: ex.operation,
+        swapToken: ex.swapToken ?? ex.fromTokenSymbol ?? ex.fromToken,
+        receiveToken: ex.receiveToken ?? ex.toTokenSymbol ?? ex.toToken,
+        amount: (ex.amount ?? ex.amountSwap ?? ex.fromAmount) as unknown,
+        chainId: ex.chainId ?? ex.fromChainId ?? ex.toChainId,
+      };
+      scope.setExtra('exchange_error_data', essentialData);
+    }
♻️ Duplicate comments (1)
src/apps/the-exchange/index.tsx (1)

171-175: Same as above: extra fields are dropped

lifi_config_init error passes walletAddress only; util currently discards it. Extend util to tag wallet when provided.

🧹 Nitpick comments (7)
src/components/BottomMenuModal/SendModal/SendModalBottomButtons.tsx (1)

31-33: Consider removing the unused allowBatching prop.

The allowBatching prop is defined but never used. The batch button visibility is already controlled by the presence of onAddToBatch. Unless there's a specific near-term plan to use this prop, consider removing it to reduce maintenance overhead.

-  // Disabled line check here as we may need this in future
-  // eslint-disable-next-line @typescript-eslint/no-unused-vars
-  allowBatching = true,
+  allowBatching = true,

If allowBatching will control independent logic in the future, document that plan in a TODO comment for clarity.

src/main.tsx (3)

69-79: Always reduce extras to an allowlist

Currently extras are trimmed only when >5 keys, which can still leak non‑essential extras. Reduce to an allowlist regardless of count.

-    // Remove large extra data
-    if (filteredEvent.extra && Object.keys(filteredEvent.extra).length > 5) {
-      const essentialKeys = ['error_data', 'exchange_error_data'];
-      const filteredExtra: Record<string, unknown> = {};
-      essentialKeys.forEach((key) => {
-        if (filteredEvent.extra && filteredEvent.extra[key]) {
-          filteredExtra[key] = filteredEvent.extra[key];
-        }
-      });
-      filteredEvent.extra = filteredExtra;
-    }
+    // Keep only essential extra data
+    if (filteredEvent.extra) {
+      const essentialKeys = ['error_data', 'exchange_error_data'];
+      const filteredExtra: Record<string, unknown> = {};
+      essentialKeys.forEach((key) => {
+        if (filteredEvent.extra && filteredEvent.extra[key]) {
+          filteredExtra[key] = filteredEvent.extra[key];
+        }
+      });
+      filteredEvent.extra = filteredExtra;
+    }

59-67: Preserve minimal auth context by allowlisting it

You set Sentry.setContext('authentication_state', …) elsewhere, but beforeSend removes all non‑essential contexts. Keep a tiny auth context by allowlisting it here.

-      const essentialContexts = ['runtime', 'browser'];
+      const essentialContexts = ['runtime', 'browser', 'authentication_state'];

31-35: Gate Sentry by DSN to avoid overhead in non‑Sentry envs

Avoid initializing when DSN is missing.

-  enabled: true,
+  enabled: Boolean(import.meta.env.VITE_SENTRY_DSN),
src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx (1)

200-208: Avoid excessively long transaction names derived from calldata

Including full data inflates memory/logs and can break UIs. Use a short suffix.

-          const transactionName = `tx-${chainId}-${data}`;
+          const dataSuffix = (data?.toString() ?? '').slice(0, 18);
+          const transactionName = `tx-${chainId}-${dataSuffix}`;
           const batchName = `batch-${chainId}`;
src/containers/Main.tsx (1)

151-160: Mask addresses in breadcrumbs

You log accountAddress verbatim. Prefer truncating to reduce PII while keeping utility.

-              data: {
-                accountAddress: address,
+              data: {
+                accountAddress: `${address.slice(0, 6)}...${address.slice(-4)}`,
src/apps/the-exchange/index.tsx (1)

43-46: Run initSentryForExchange once

Tags are static; re‑running on wallet UI state changes is unnecessary.

-  useEffect(() => {
-    initSentryForExchange();
-  }, [walletAddress, isSwapOpen, isReceiveOpen]);
+  useEffect(() => {
+    initSentryForExchange();
+  }, []);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bfdedf6 and 55f2180.

📒 Files selected for processing (13)
  • src/apps/the-exchange/SENTRY_LOGGING.md (0 hunks)
  • src/apps/the-exchange/components/CardsSwap/CardsSwap.tsx (0 hunks)
  • src/apps/the-exchange/components/EnterAmount/EnterAmount.tsx (1 hunks)
  • src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx (2 hunks)
  • src/apps/the-exchange/components/ExchangeAction/test/ExchangeAction.test.tsx (0 hunks)
  • src/apps/the-exchange/components/SelectToken/SelectToken.tsx (0 hunks)
  • src/apps/the-exchange/components/SwapSummary/SwapSummary.tsx (0 hunks)
  • src/apps/the-exchange/hooks/useOffer.tsx (0 hunks)
  • src/apps/the-exchange/index.tsx (4 hunks)
  • src/apps/the-exchange/utils/sentry.ts (4 hunks)
  • src/components/BottomMenuModal/SendModal/SendModalBottomButtons.tsx (1 hunks)
  • src/containers/Main.tsx (1 hunks)
  • src/main.tsx (1 hunks)
💤 Files with no reviewable changes (6)
  • src/apps/the-exchange/components/SelectToken/SelectToken.tsx
  • src/apps/the-exchange/hooks/useOffer.tsx
  • src/apps/the-exchange/components/ExchangeAction/test/ExchangeAction.test.tsx
  • src/apps/the-exchange/components/SwapSummary/SwapSummary.tsx
  • src/apps/the-exchange/components/CardsSwap/CardsSwap.tsx
  • src/apps/the-exchange/SENTRY_LOGGING.md
🧰 Additional context used
🧬 Code graph analysis (2)
src/apps/the-exchange/index.tsx (1)
src/apps/the-exchange/utils/sentry.ts (1)
  • logExchangeError (17-53)
src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx (1)
src/apps/the-exchange/utils/sentry.ts (1)
  • logExchangeError (17-53)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint
  • GitHub Check: unit-tests
  • GitHub Check: build
🔇 Additional comments (3)
src/components/BottomMenuModal/SendModal/SendModalBottomButtons.tsx (1)

39-53: LGTM! Sentry logging removed as intended.

The removal of Sentry context and breadcrumb logging aligns with the PR objectives. All button handlers remain functionally intact, and the comments clearly document where logging was removed, which will be helpful when reintroducing logging later.

src/containers/Main.tsx (1)

78-91: authentication_state context currently gets dropped

beforeSend only keeps runtime/browser. Either remove this setContext or keep it minimal and allowlist via src/main.tsx change suggested earlier. I recommend the latter so you retain a tiny auth snapshot without quota impact.
Would you like me to wire a tiny helper to set a masked auth context only on errors?

src/apps/the-exchange/index.tsx (1)

146-154: Ensure chainId and wallet are preserved by logExchangeError

Current util ignores chainId and walletAddress. Either pass recognized keys (swapToken, receiveToken, amount) or extend the util to capture chainId and wallet tag (see utils/sentry.ts comment). If you keep these fields, adopt the util enhancement so they persist.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/containers/Main.tsx (1)

105-106: Comment could be more specific.

The comment "Remove breadcrumb logging to save quota" documents the change but doesn't indicate what breadcrumb was removed (e.g., "User authenticated" breadcrumb, Privy authentication state, etc.). While the intent is clear, being more specific helps future maintainers understand exactly what was removed and why.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55f2180 and 5ed5485.

📒 Files selected for processing (1)
  • src/containers/Main.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint
  • GitHub Check: unit-tests
  • GitHub Check: build

Comment on lines +78 to 100
// Minimal Sentry context for authentication state - only set on errors
useEffect(() => {
Sentry.setContext('authentication_state', {
ready,
authenticated,
hasUser: !!user,
hasWallets: wallets.length > 0,
wagmiIsConnected,
isAppReady,
isAuthenticated,
previouslyAuthenticated,
userAgent: navigator.userAgent,
timestamp: new Date().toISOString(),
});

if (isAuthenticated) {
Sentry.addBreadcrumb({
category: 'authentication',
message: 'User authenticated',
level: 'info',
data: {
authenticated,
wagmiIsConnected,
walletsCount: wallets.length,
},
// Only set context if there's an authentication error
if (!isAuthenticated && ready && isAppReady) {
Sentry.setContext('authentication_state', {
ready,
authenticated,
isAppReady,
isAuthenticated,
timestamp: new Date().toISOString(),
wagmiIsConnected,
hasUser: !!user,
userAddress: user?.wallet?.address,
});
}
}, [
ready,
authenticated,
user,
wagmiIsConnected,
isAppReady,
isAuthenticated,
previouslyAuthenticated,
wallets.length,
user,
wagmiIsConnected,
]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reconsider the "error-focused" logging approach.

The comment claims this is "error-focused" logging that only sets context "on errors", but the condition !isAuthenticated && ready && isAppReady checks for a normal "not yet authenticated" state, not an error condition. This will still execute during normal app initialization flows and consume Sentry quota.

Additionally:

  • Line 90 captures userAddress when !isAuthenticated, which seems contradictory—if the user isn't authenticated, why capture their address?
  • The dependencies (user, wagmiIsConnected) will cause this effect to re-run frequently during authentication transitions, potentially setting context multiple times.

If the goal is truly error-focused logging to reduce quota usage, consider:

  1. Only setting context when specific error conditions occur (e.g., authentication failures, timeouts, exceptions).
  2. Removing or throttling context updates during normal state transitions.
  3. Reconsidering whether to capture user data when not authenticated.
🤖 Prompt for AI Agents
In src/containers/Main.tsx around lines 78-100: the useEffect currently runs for
a normal "not yet authenticated" state (condition: !isAuthenticated && ready &&
isAppReady), causing non-error Sentry context updates, capturing userAddress
despite not being authenticated, and re-running frequently due to broad
dependencies. Change the guard to only run on actual authentication error
conditions (e.g., an authError flag, timeout, or caught exception) instead of
generic !isAuthenticated; do not include userAddress when user is not
authenticated (remove or conditionally include it only when authenticated);
reduce effect dependencies to only error-related values and/or add a
one-time/throttling mechanism (ref or timestamp check) so context is set only
once per error occurrence.

);
});
};
// Remove all other logging functions to save quota
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

allowBatching,
estimatedCostFormatted,
]);
// Remove Sentry context logging to save quota
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

},
});

// Remove breadcrumb logging to save quota
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

},
});

// Remove breadcrumb logging to save quota
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

},
});

// Remove breadcrumb logging to save quota
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

},
});
}, [authenticated, user, wallets.length]);
// Remove breadcrumb logging to save quota
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/apps/the-exchange/utils/sentry.ts (1)

3-7: Fix useEffect to initialize Sentry only once on app startup.

The initSentryForExchange() call in src/apps/the-exchange/index.tsx (line 44) runs every time walletAddress, isSwapOpen, or isReceiveOpen changes because of the dependency array [walletAddress, isSwapOpen, isReceiveOpen]. Change the dependency array to an empty array [] so initialization runs exactly once when the component mounts:

useEffect(() => {
  initSentryForExchange();
}, []);
🧹 Nitpick comments (10)
src/main.tsx (5)

35-37: Replay keys are unused; consider zeroing traces and removing replay config.

Replay is disabled; keep config lean and unambiguous. Also set tracesSampleRate to 0 unless you intend to re-enable tracing soon.

Apply:

-  tracesSampleRate: 0.01, // Only capture 1% of performance traces
-  replaysSessionSampleRate: 0,
-  replaysOnErrorSampleRate: 0,
+  // No tracing or replay
+  tracesSampleRate: 0,

35-37: Prefer SDK-level breadcrumb cap over post-hoc slicing.

Set maxBreadcrumbs to 10 to avoid collecting excess in the first place.

Apply:

   environment: import.meta.env.VITE_SENTRY_ENVIRONMENT ?? 'staging',
+  maxBreadcrumbs: 10,

54-66: Strip PII-prone top-level fields too.

Remove user and request objects to avoid accidental PII.

Apply:

       filteredEvent.contexts = filteredContexts;
     }
 
+    // Strip PII-prone fields
+    delete (filteredEvent as any).user;
+    delete (filteredEvent as any).request;

67-77: Always whitelist extra keys; don’t rely on a length threshold.

Trim extra to the allowed set regardless of count and drop undefineds.

Apply:

-    if (filteredEvent.extra && Object.keys(filteredEvent.extra).length > 5) {
-      const essentialKeys = ['error_data', 'exchange_error_data'];
-      const filteredExtra: Record<string, unknown> = {};
-      essentialKeys.forEach((key) => {
-        if (filteredEvent.extra && filteredEvent.extra[key]) {
-          filteredExtra[key] = filteredEvent.extra[key];
-        }
-      });
-      filteredEvent.extra = filteredExtra;
-    }
+    if (filteredEvent.extra) {
+      const essentialKeys = ['error_data', 'exchange_error_data'] as const;
+      const filteredExtra: Record<string, unknown> = {};
+      for (const k of essentialKeys) {
+        const v = (filteredEvent.extra as any)[k];
+        if (v !== undefined) filteredExtra[k] = v;
+      }
+      filteredEvent.extra = filteredExtra;
+    }

35-37: Optional: gate Sentry by DSN and prod.

Avoid initializing when DSN is absent or in non-prod. Keeps local/dev clean.

Example:

const DSN = import.meta.env.VITE_SENTRY_DSN;
const enabled = Boolean(DSN) && import.meta.env.PROD;
if (enabled) {
  Sentry.init({ dsn: DSN, /* ... */ });
}
src/apps/the-exchange/utils/sentry.ts (5)

25-29: Unify tag names; drop app_module to avoid duplicate semantics.

You already set app/module globally in init. Keep a single convention.

Apply:

-    scope.setTag('app_module', 'the-exchange');
     scope.setTag('error_type', 'exchange_error');

36-45: Whitelist and de-undef extra; coerce amount to a safe primitive.

Keeps payload tight and deterministic.

Apply:

-      const essentialData = {
-        operation: extra.operation,
-        swapToken: extra.swapToken,
-        receiveToken: extra.receiveToken,
-        amount: extra.amount,
-      };
+      const essentialData = Object.fromEntries(
+        Object.entries({
+          operation: (extra as any).operation,
+          swapToken: (extra as any).swapToken,
+          receiveToken: (extra as any).receiveToken,
+          amount:
+            typeof (extra as any).amount === 'object'
+              ? String((extra as any).amount)
+              : (extra as any).amount,
+        }).filter(([, v]) => v !== undefined)
+      );

24-52: Return the event id for correlation.

Capture the id inside withScope and return it from the function.

Apply:

 export const logExchangeError = (
   error: Error | string,
   extra?: Record<string, unknown>,
   tags?: Record<string, string>
 ) => {
   const walletAddress = fallbackWalletAddressForLogging();
+  let eventId: string | undefined;
 
   Sentry.withScope((scope) => {
@@
-    if (error instanceof Error) {
-      Sentry.captureException(error);
-    } else {
-      Sentry.captureMessage(error, 'error');
-    }
+    eventId =
+      error instanceof Error
+        ? Sentry.captureException(error)
+        : Sentry.captureMessage(error as string, 'error');
   });
+
+  return eventId;
 };

9-14: Update stale comment or accept wallet address as a param.

Function always returns 'unknown_wallet_address'; the “component context” note is misleading.

Apply:

-// This function should be called from within a React component context
-// where the wallet address is available
+// Fallback when the wallet address is not available or must not be logged

Alternative: accept an optional walletAddress in logExchangeError and set the tag only if provided.


55-59: Naming: use implies a React Hook.*

Consider an alias to avoid rules-of-hooks confusion while keeping BC.

Apply:

 export const useWalletAddressForLogging = () => {
   // This hook is kept for compatibility but returns minimal data
   return 'unknown_wallet_address';
 };
+
+// Back-compat alias with a non-hook name (preferred for new code)
+export const getWalletAddressForLogging = useWalletAddressForLogging;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ed5485 and 2544471.

📒 Files selected for processing (4)
  • src/apps/the-exchange/utils/sentry.ts (4 hunks)
  • src/components/BottomMenuModal/SendModal/SendModalBottomButtons.tsx (1 hunks)
  • src/containers/Main.tsx (1 hunks)
  • src/main.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/BottomMenuModal/SendModal/SendModalBottomButtons.tsx
  • src/containers/Main.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint
  • GitHub Check: unit-tests
  • GitHub Check: build

Comment on lines +41 to 44
// Only send error-level events to Sentry
if (event.level && event.level !== 'error' && event.level !== 'fatal') {
return null; // Drop the event
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Non-error events with missing level still pass. Tighten the drop condition.

Only allow exceptions or explicit error/fatal. Otherwise drop.

Apply:

-    // Only send error-level events to Sentry
-    if (event.level && event.level !== 'error' && event.level !== 'fatal') {
-      return null; // Drop the event
-    }
+    // Only send exceptions or explicit error/fatal levels
+    const isError =
+      (event as any).exception != null ||
+      event.level === 'error' ||
+      event.level === 'fatal';
+    if (!isError) return null;
🤖 Prompt for AI Agents
In src/main.tsx around lines 41 to 44, the current filter only drops events when
event.level exists and is not 'error'/'fatal', allowing events with missing
level to pass; change the condition to only allow events that are exceptions or
have an explicit 'error' or 'fatal' level. Replace the current if with a guard
that returns null unless event.exception is present OR event.level === 'error'
OR event.level === 'fatal', ensuring all other events (including those with no
level) are dropped.

@IAmKio IAmKio merged commit ebaf571 into staging Oct 24, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 5, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants