diff --git a/src/components/messages/ThreadWindow/index.tsx b/src/components/messages/ThreadWindow/index.tsx index c5ae9c38..677d5741 100644 --- a/src/components/messages/ThreadWindow/index.tsx +++ b/src/components/messages/ThreadWindow/index.tsx @@ -10,6 +10,7 @@ import BackButton from '@/components/general/BackButton' import Text from '@/components/general/Text' import W3iContext from '@/contexts/W3iContext/context' import { getEthChainAddress } from '@/utils/address' +import { logError } from '@/utils/error' import { truncate } from '@/utils/string' import type { ChatClientTypes } from '@/w3iProxy/chatProviders/types' import type { ReplayMessage } from '@/w3iProxy/w3iChatFacade' @@ -70,7 +71,7 @@ const ThreadWindow: React.FC = () => { setMessages(allChatMessages) }) .catch(() => { - console.error('getMessages failed, redirecting to root') + logError(new Error('getMessages failed, redirecting to root')) nav('/') }) @@ -78,7 +79,7 @@ const ThreadWindow: React.FC = () => { // Not using `threads` to avoid a data race. chatClientProxy.getThreads({ account: `eip155:1:${userPubkey}` }).then(retreivedThreads => { if (!retreivedThreads.get(topic)) { - console.error('topic not in threads, redirecting to root') + logError(new Error('topic not in threads, redirecting to root')) nav('/') } }) diff --git a/src/components/notifications/AppExplorer/AppCard/index.tsx b/src/components/notifications/AppExplorer/AppCard/index.tsx index a79103d5..6e97def5 100644 --- a/src/components/notifications/AppExplorer/AppCard/index.tsx +++ b/src/components/notifications/AppExplorer/AppCard/index.tsx @@ -7,6 +7,7 @@ import SpannerSVG from '@/assets/Spanner.svg' import Badge from '@/components/general/Badge' import Text from '@/components/general/Text' import W3iContext from '@/contexts/W3iContext/context' +import { logError } from '@/utils/error' import { showErrorMessageToast, showSuccessMessageToast } from '@/utils/toasts' import SubscribeButton from './SubscribeButton' @@ -69,7 +70,7 @@ const AppCard: React.FC = ({ appDomain: new URL(url).host }) } catch (error) { - console.error(error) + logError(error) setSubscribing(false) showErrorMessageToast(`Failed to subscribe to ${name}`) } @@ -88,7 +89,7 @@ const AppCard: React.FC = ({ throw new Error(`No matching subscription found to domain, ${appDomain}`) } } catch (e: any) { - console.error(`Failed to navigate to app: ${e.message}`) + logError(e) } } } diff --git a/src/components/notifications/NotificationsLayout/PreferencesModal/index.tsx b/src/components/notifications/NotificationsLayout/PreferencesModal/index.tsx index 9603894e..f37f8025 100644 --- a/src/components/notifications/NotificationsLayout/PreferencesModal/index.tsx +++ b/src/components/notifications/NotificationsLayout/PreferencesModal/index.tsx @@ -10,6 +10,7 @@ import Text from '@/components/general/Text' import Toggle from '@/components/general/Toggle' import SettingsContext from '@/contexts/SettingsContext/context' import W3iContext from '@/contexts/W3iContext/context' +import { logError } from '@/utils/error' import { useColorModeValue, useModals } from '@/utils/hooks' import { preferencesModalService } from '@/utils/store' import { showErrorMessageToast, showSuccessMessageToast } from '@/utils/toasts' @@ -61,7 +62,7 @@ export const PreferencesModal: React.FC = () => { scope: getEnabledScopes(scopes) }) } catch (error) { - console.error(error) + logError(error) showErrorMessageToast('Failed to update preferences') setLoading(false) } diff --git a/src/components/notifications/NotificationsLayout/UnsubscribeModal/index.tsx b/src/components/notifications/NotificationsLayout/UnsubscribeModal/index.tsx index d9225e56..63501c86 100644 --- a/src/components/notifications/NotificationsLayout/UnsubscribeModal/index.tsx +++ b/src/components/notifications/NotificationsLayout/UnsubscribeModal/index.tsx @@ -8,6 +8,7 @@ import { Modal } from '@/components/general/Modal/Modal' import Spinner from '@/components/general/Spinner' import Text from '@/components/general/Text' import W3iContext from '@/contexts/W3iContext/context' +import { logError } from '@/utils/error' import { useModals } from '@/utils/hooks' import { unsubscribeModalService } from '@/utils/store' import { showDefaultToast, showErrorMessageToast } from '@/utils/toasts' @@ -39,7 +40,7 @@ export const UnsubscribeModal: React.FC = () => { }) await notifyClientProxy.deleteSubscription({ topic: unsubscribeModalAppId }) } catch (error) { - console.error(error) + logError(error) showErrorMessageToast(`Unsubscribing failed, please try again`) setLoading(false) } diff --git a/src/contexts/W3iContext/hooks/notifyHooks.ts b/src/contexts/W3iContext/hooks/notifyHooks.ts index 7a1adf35..fe258702 100644 --- a/src/contexts/W3iContext/hooks/notifyHooks.ts +++ b/src/contexts/W3iContext/hooks/notifyHooks.ts @@ -4,6 +4,7 @@ import type { NotifyClientTypes } from '@walletconnect/notify-client' import { useNavigate } from 'react-router-dom' import { noop } from 'rxjs' +import { logError } from '@/utils/error' import type Web3InboxProxy from '@/w3iProxy' import type { W3iNotifyClient } from '@/w3iProxy' @@ -90,7 +91,7 @@ export const useNotifyState = (w3iProxy: Web3InboxProxy, proxyReady: boolean) => setRegistered(identityKey) refreshNotifyState() } catch (error) { - console.error(error) + logError(error) setRegisterMessage(null) } } diff --git a/src/contexts/W3iContext/hooks/w3iProxyHooks.ts b/src/contexts/W3iContext/hooks/w3iProxyHooks.ts index ed8966ef..1a2db868 100644 --- a/src/contexts/W3iContext/hooks/w3iProxyHooks.ts +++ b/src/contexts/W3iContext/hooks/w3iProxyHooks.ts @@ -2,6 +2,8 @@ import { useEffect, useState } from 'react' +import { logError } from '@/utils/error' + import Web3InboxProxy from '../../../w3iProxy' import { useDappOrigin } from './dappOrigin' import { useProviderQueries } from './providerQueryHooks' @@ -34,7 +36,7 @@ export const useW3iProxy = () => { setReady(true) }) .catch(error => { - console.error('w3iProxy failed to initialize: ', error) + logError(error) }) } }, [w3iProxy.isInitializing]) diff --git a/src/pages/Login/SignatureModal/index.tsx b/src/pages/Login/SignatureModal/index.tsx index b2f06393..a86ad15a 100644 --- a/src/pages/Login/SignatureModal/index.tsx +++ b/src/pages/Login/SignatureModal/index.tsx @@ -9,6 +9,7 @@ import SignatureIcon from '@/components/general/Icon/SignatureIcon' import Wallet from '@/components/general/Icon/Wallet' import { Modal } from '@/components/general/Modal/Modal' import Text from '@/components/general/Text' +import { logError } from '@/utils/error' import { useModals } from '@/utils/hooks' import { signatureModalService } from '@/utils/store' @@ -42,7 +43,7 @@ export const SignatureModal: React.FC<{ ) break default: - console.error('No correct sender for signature modal') + logError(new Error(`No correct sender for signature modal, sender: ${sender}`)) } }) .catch(() => { diff --git a/src/pages/ScanQrCode/index.tsx b/src/pages/ScanQrCode/index.tsx index 9b35abdd..9affab54 100644 --- a/src/pages/ScanQrCode/index.tsx +++ b/src/pages/ScanQrCode/index.tsx @@ -5,6 +5,7 @@ import { useNavigate } from 'react-router-dom' import BackButton from '@/components/general/BackButton' import TransitionDiv from '@/components/general/TransitionDiv' +import { logError } from '@/utils/error' import './ScanQrCode.scss' @@ -22,7 +23,7 @@ const ScanQrCode: React.FC = () => { if (web3inboxRegex.test(scanResult)) { nav(scanResult.replace(window.location.origin, '')) } else { - console.error('Not a valid invite url', scanResult) + logError(new Error(`Not a valid invite url: ${scanResult}`)) nav('/messages') } }, [scanResult]) diff --git a/src/pages/widget/Subscribe/index.tsx b/src/pages/widget/Subscribe/index.tsx index 016d351f..c150b9d3 100644 --- a/src/pages/widget/Subscribe/index.tsx +++ b/src/pages/widget/Subscribe/index.tsx @@ -7,6 +7,7 @@ import W3iBellIcon from '@/assets/W3iBell.svg' import Button from '@/components/general/Button' import Spinner from '@/components/general/Spinner' import W3iContext from '@/contexts/W3iContext/context' +import { logError } from '@/utils/error' import { showErrorMessageToast } from '@/utils/toasts' import { JsCommunicator } from '@/w3iProxy/externalCommunicators/jsCommunicator' @@ -43,7 +44,7 @@ const WidgetSubscribe: React.FC = () => { appDomain: new URL(dappOrigin).host }) } catch (error) { - console.error(error) + logError(error) showErrorMessageToast(`Failed to subscribe to ${dappOrigin}`) } finally { setIsSubscribing(false) diff --git a/src/utils/error.ts b/src/utils/error.ts new file mode 100644 index 00000000..47167ac9 --- /dev/null +++ b/src/utils/error.ts @@ -0,0 +1,6 @@ +import { captureException } from '@sentry/react' + +export const logError = (error: any) => { + console.error(error) + captureException(error) +} diff --git a/src/utils/hooks/useNotifyProjects.ts b/src/utils/hooks/useNotifyProjects.ts index 9b8a3853..d6e93a66 100644 --- a/src/utils/hooks/useNotifyProjects.ts +++ b/src/utils/hooks/useNotifyProjects.ts @@ -5,6 +5,8 @@ import SettingsContext from '@/contexts/SettingsContext/context' import { fetchDomainProjects, fetchFeaturedProjects } from '@/utils/projects' import type { INotifyApp, INotifyProject, INotifyProjectWithComingSoon } from '@/utils/types' +import { logError } from '../error' + const useNotifyProjects = () => { const [loading, setLoading] = useState(false) const [projects, setProjects] = useState([]) @@ -51,7 +53,7 @@ const useNotifyProjects = () => { setProjects(notifyApps) } catch (error) { - console.error(error) + logError(error) setProjects([]) } finally { setLoading(false) diff --git a/src/utils/notifications.ts b/src/utils/notifications.ts index d541871d..9db32535 100644 --- a/src/utils/notifications.ts +++ b/src/utils/notifications.ts @@ -90,7 +90,7 @@ export const userEnabledNotification = () => { */ export const requireNotifyPermission = async () => { if (!notificationsEnabledInBrowser()) { - console.error('This browser does not support desktop push notifications') + console.warn('This browser does not support desktop push notifications') return false } @@ -100,7 +100,7 @@ export const requireNotifyPermission = async () => { case 'granted': return true case 'denied': - console.error('User denied permissions') + console.warn('User denied permissions') return false default: return (await window.Notification?.requestPermission()) === 'granted' diff --git a/src/utils/projects.ts b/src/utils/projects.ts index d7de5c7c..b253225b 100644 --- a/src/utils/projects.ts +++ b/src/utils/projects.ts @@ -10,9 +10,7 @@ export async function fetchFeaturedProjects() { explorerUrlFeatured.searchParams.set('isFeatured', 'true') try { - const discoverProjectsData = await fetch(explorerUrlFeatured) - .then(async res => res.json()) - .catch(err => console.error({ featuredProjects: err })) + const discoverProjectsData = await fetch(explorerUrlFeatured).then(async res => res.json()) const discoverProjects = Object.values(discoverProjectsData.projects) return { diff --git a/src/w3iProxy/notifyProviders/internalNotifyProvider.ts b/src/w3iProxy/notifyProviders/internalNotifyProvider.ts index d8fb5121..d33d63f3 100644 --- a/src/w3iProxy/notifyProviders/internalNotifyProvider.ts +++ b/src/w3iProxy/notifyProviders/internalNotifyProvider.ts @@ -4,6 +4,7 @@ import type { NotifyClient } from '@walletconnect/notify-client' import type { EventEmitter } from 'events' import mixpanel from 'mixpanel-browser' +import { logError } from '@/utils/error' import { getDbEchoRegistrations } from '@/utils/idb' import { notificationsEnabledInBrowser, @@ -193,7 +194,7 @@ export default class InternalNotifyProvider implements W3iNotifyProvider { // Ensure we have a registration with echo (if we need it) await this.ensureEchoRegistration() } catch (e) { - Sentry.captureEvent(e as Error) + logError(e) } return subscribed @@ -208,7 +209,7 @@ export default class InternalNotifyProvider implements W3iNotifyProvider { ? this.notifyClient.subscriptions.get(params.topic).account : '' - const isRegistered = this.notifyClient.isRegistered({ + const isRegistered = this.notifyClient.isRegistered({ account, domain: window.location.hostname, allApps: true diff --git a/src/w3iProxy/w3iChatFacade.ts b/src/w3iProxy/w3iChatFacade.ts index 4ee2a736..c4e6cfc5 100644 --- a/src/w3iProxy/w3iChatFacade.ts +++ b/src/w3iProxy/w3iChatFacade.ts @@ -6,6 +6,8 @@ import { EventEmitter } from 'events' import { ReplaySubject, filter, from, scan, throwError, timeout } from 'rxjs' import { hashMessage } from 'viem' +import { logError } from '@/utils/error' + import ExternalChatProvider from './chatProviders/externalChatProvider' // eslint-disable-next-line no-duplicate-imports import type { ChatClientTypes } from './chatProviders/types' @@ -151,7 +153,7 @@ class W3iChatFacade implements W3iChat { // eslint-disable-next-line public async initInternalProvider(chatClient: any) { - console.error('Initting internal chat provider not supported') + logError(new Error('Initting internal chat provider not supported')) } // Method to be used by external providers. Not internal use.