From 9329eaf3a9063edb0be85278e688d9c21ec84cbf Mon Sep 17 00:00:00 2001 From: Mo Tarbin Date: Sun, 16 Aug 2026 13:13:00 -0400 Subject: [PATCH] update consent handling and remove unused error capture logic --- src/analytics/consent.js | 3 ++- src/analytics/eventSchemas.js | 6 ------ src/analytics/index.js | 20 +++----------------- src/utils/ApiClient.js | 12 ------------ 4 files changed, 5 insertions(+), 36 deletions(-) diff --git a/src/analytics/consent.js b/src/analytics/consent.js index b9862f0..68ebbf5 100644 --- a/src/analytics/consent.js +++ b/src/analytics/consent.js @@ -2,7 +2,8 @@ import { Preferences } from '@capacitor/preferences' // Two independent consent axes, matching the existing onboarding UI // (HeardAboutView's PrivacyPreferences): "analytics" gates track(), "crash" -// gates captureError(). A self-hosted user can opt into one without the other. +// gates captureException(). A self-hosted user can opt into one without the +// other. const CONSENT_KEYS = { analytics: 'analytics_consent', crash: 'analytics_crash_consent', diff --git a/src/analytics/eventSchemas.js b/src/analytics/eventSchemas.js index 4d164aa..3145f7e 100644 --- a/src/analytics/eventSchemas.js +++ b/src/analytics/eventSchemas.js @@ -79,12 +79,6 @@ export const EVENT_SCHEMAS = { } export const ERROR_SCHEMAS = { - api_error: { - http_status: 'string', - method: 'string', - error_code: 'string', - operation: 'string', - }, // No message/stack field here by design — those come from the real Error // object passed to posthog.captureException() itself, not from this // sanitized properties bag. This schema only classifies how it was caught. diff --git a/src/analytics/index.js b/src/analytics/index.js index b16d7e1..a276283 100644 --- a/src/analytics/index.js +++ b/src/analytics/index.js @@ -142,20 +142,6 @@ export const track = (eventName, properties = {}) => { posthog.capture(eventName, sanitized) } -/** Backend/API failures: a normal sanitized event, same as track() — not - * PostHog's Error Tracking product. There's no real Error object here (just - * an HTTP response), so there's no stack trace to gain from captureException. */ -export const captureError = (errorType, properties = {}) => { - if (!canSend('crash')) return - const posthog = getClientSync() - if (!posthog) return - - const sanitized = sanitizeErrorProperties(errorType, properties) - if (!sanitized) return - - posthog.capture(errorType, sanitized) -} - /** * Frontend crashes only. Uses captureException (not capture) so these land * on PostHog's Error Tracking page with a genuine message + stack trace — @@ -176,7 +162,7 @@ export const captureException = (error, properties = {}) => { let globalHandlersInstalled = false /** Reports uncaught exceptions and unhandled promise rejections to - * PostHog's Error Tracking, gated by the same crash consent as api_error. + * PostHog's Error Tracking, gated by crash consent. * Complements, doesn't overlap with, src/views/Error.jsx: that's a React * Router error-boundary screen for render/loader errors, which React catches * before they ever reach window.onerror — a different class of failure, with @@ -206,7 +192,7 @@ export const installGlobalErrorHandlers = () => { /** * kind: 'analytics' | 'crash'. Enabling analytics (re-)initializes PostHog * if needed and sends analytics_enabled; enabling crash-only never talks to - * PostHog by itself (it only unlocks captureError once something reports). + * PostHog by itself (it only unlocks captureException once something crashes). * Disabling never sends an event and clears identity/queued data. */ export const setConsent = async (kind, value, { source } = {}) => { @@ -236,7 +222,7 @@ export const setConsent = async (kind, value, { source } = {}) => { } else if (kind === 'crash') { // Crash reporting alone doesn't need PostHog started with the analytics // super-properties path, but it does need a live client + identity to - // send captureError() calls through. + // send captureException() calls through. if (isConfigured() && !getClientSync()) { await startPosthog() } diff --git a/src/utils/ApiClient.js b/src/utils/ApiClient.js index 6560c5e..1d78e60 100644 --- a/src/utils/ApiClient.js +++ b/src/utils/ApiClient.js @@ -1,10 +1,8 @@ import { Preferences } from '@capacitor/preferences' -import { captureError } from '../analytics' import { API_URL } from '../Config' import { networkManager } from '../hooks/NetworkManager' import { - normalizeEndpoint, recordApiFailure, recordServerVersionFromResponse, } from '../service/DiagnosticsSession' @@ -230,11 +228,6 @@ class ApiClient { method: config.method, status: response.status, }) - captureError('api_error', { - http_status: String(response.status), - method: config.method || 'GET', - operation: normalizeEndpoint(endpoint), - }) } // 2. Check for 401 (Unauthorized) @@ -319,11 +312,6 @@ class ApiClient { if (!externalAbort) { networkManager.setServerUnreachable() recordApiFailure({ endpoint, method: config.method, status: 'network' }) - captureError('api_error', { - http_status: 'network', - method: config.method || 'GET', - operation: normalizeEndpoint(endpoint), - }) } console.error('Request failed', error) throw error