Skip to content

Commit

Permalink
Improve sentry log (#2553)
Browse files Browse the repository at this point in the history
* refactor Sentry error

* fix to warn only known error patterns

* add some comment to ignored issues
  • Loading branch information
tienkane authored Oct 25, 2024
1 parent 5b736c2 commit cf21c13
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/hooks/useEthersProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function clientToProvider(client?: Client<Transport, Chain>, chainId?: number) {
}
const { chain, transport } = client

const ensAddress = chain.contracts?.ensRegistry?.address
const ensAddress = chain?.contracts?.ensRegistry?.address
const network = chain
? {
chainId: chain.id,
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useLogin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const useLogin = (autoLogin = false) => {
} catch (error) {
const e = new Error('createProfile Error', { cause: error })
e.name = 'createProfile Error'
captureException(e, { extra: { walletAddress, account } })
captureException(e, { extra: { walletAddress, account }, level: 'warning' })
setProfile({ profile: undefined, isAnonymous, account })
}
},
Expand Down
23 changes: 21 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,29 @@ if (ENV_LEVEL > ENV_TYPE.LOCAL) {
environment: 'production',
ignoreErrors: ['AbortError'],
integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()],
tracesSampleRate: 0.1,
tracesSampleRate: 1.0,
normalizeDepth: 5,
replaysSessionSampleRate: 0.1,
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
beforeSend(event, hint) {
const error = hint?.originalException as Error
const { name, message } = error
if (
(name === 'TypeError' && message === 'Load failed') || // Almost come from mobile safari fetch API issues
(name === 'ChunkLoadError' && message.includes('Failed to fetch')) || // https://sentry.io/answers/chunk-load-errors-javascript/
(name === 'Error' && message.includes('Java object is gone')) || // coming from the WebView to Java bridge in Chrome, something went wrong with Chrome Mobile WebView from some Android devices
(name === 'UnhandledRejection' && message.includes('Non-Error promise rejection captured with value')) ||
(name === '<unknown>' && message.includes('Non-Error promise rejection captured with value')) || // this always happens when a some external library throws an error, checked with all issues in Sentry logs
(name === '<unknown>' && message.includes('Object captured as promise rejection with keys')) // this always happens when a some external library throws an error, checked with all issues in Sentry logs
)
return null

if (name === 'TypeError' && message.includes('Failed to fetch')) {
event.level = 'warning'
}

return event
},
})
Sentry.setTag('request_id', sentryRequestId)
Sentry.setTag('version', TAG)
Expand Down
2 changes: 1 addition & 1 deletion src/state/transactions/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const initialState: TransactionState = {}
const clearOldTransactions = (transactions: GroupedTxsByHash | undefined): GroupedTxsByHash | undefined => {
if (!transactions) return undefined
const chainTxs = Object.values(transactions ?? {}).filter(Boolean) as TransactionDetails[][]
chainTxs.sort((a, b) => a[0].addedTime - b[0].addedTime)
chainTxs.sort((a, b) => (a[0]?.addedTime || 0) - (b[0]?.addedTime || 0))
const slicedChainTxs = chainTxs.slice(-10).filter(tx => tx[0].addedTime > Date.now() - 7 * 24 * 60 * 60 * 1000)
const result = slicedChainTxs.reduce((acc, cur) => ({ ...acc, [cur[0].hash]: cur }), {}) as GroupedTxsByHash
return result
Expand Down
47 changes: 31 additions & 16 deletions src/utils/errorMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@ import { capitalizeFirstLetter } from 'utils/string'
const matchPatterns = (patterns: string[], error: string) =>
patterns.some(pattern => error.toLowerCase().includes(pattern.toLowerCase()))

export const knownPatterns = {
insufficient_erc20_balance: 'Insufficient ERC20 balance to pay gas fee',
router_expired: 'An error occurred. Refresh the page and try again.',
already_pending: 'Pending request(s), please approve it in your wallet.',
mintotalamountout: 'An error occurred. Try refreshing the price rate or increase max slippage.',
from_address_mismatch: 'The requested account and/or method has not been authorized by the user.',
insufficient_funds: 'Your current balance falls short of covering the required gas fee.',
swap_failed:
'An error occurred. Refresh the page and try again. If the issue still persists, it might be an issue with your RPC node settings in Metamask.',
underlying_network_changed: 'Your chain is mismatched, please make sure your wallet is switch to the expected chain.',
user_rejected: 'User rejected the transaction.',
insufficient: 'An error occurred. Please try increasing max slippage.',
permit: 'An error occurred. Invalid Permit Signature.',
burn_amount_exceeds_balance:
'Insufficient fee rewards amount, try to remove your liquidity without claiming fees for now and you can try to claim it later.',
object_object: 'Something went wrong. Please try again.',
}

function parseKnownPattern(text: string): string | undefined {
const error = text?.toLowerCase?.() || ''

if (matchPatterns(['insufficient erc20 balance'], error)) return t`Insufficient ERC20 balance to pay gas fee`
if (matchPatterns(['insufficient erc20 balance'], error)) return knownPatterns.insufficient_erc20_balance

if (!error || error.includes('router: expired')) return t`An error occurred. Refresh the page and try again.`
if (!error || error.includes('router: expired')) return knownPatterns.router_expired

if (matchPatterns(['already pending'], error)) return t`Pending request(s), please approve it in your wallet.`
if (matchPatterns(['already pending'], error)) return knownPatterns.already_pending

if (
matchPatterns(
Expand All @@ -28,41 +46,38 @@ function parseKnownPattern(text: string): string | undefined {
error,
)
)
return t`An error occurred. Try refreshing the price rate or increase max slippage.`
return knownPatterns.mintotalamountout

if (
matchPatterns(
['The requested account and/or method has not been authorized by the user', 'From address mismatch'],
error,
)
)
return t`The requested account and/or method has not been authorized by the user.`
return knownPatterns.from_address_mismatch

if (
matchPatterns(
['insufficient funds for intrinsic transaction cost', 'OutOfFund', 'insufficient balance for transfer'],
error,
)
)
return t`Your current balance falls short of covering the required gas fee.`
return knownPatterns.insufficient_funds

if (matchPatterns(['header not found', 'swap failed'], error))
return t`An error occurred. Refresh the page and try again. If the issue still persists, it might be an issue with your RPC node settings in Metamask.`
if (matchPatterns(['header not found', 'swap failed'], error)) return knownPatterns.swap_failed

if (matchPatterns(['underlying network changed'], error))
return t`Your chain is mismatched, please make sure your wallet is switch to the expected chain.`
if (matchPatterns(['underlying network changed'], error)) return knownPatterns.underlying_network_changed

if (didUserReject(error)) return t`User rejected the transaction.`
if (didUserReject(error)) return knownPatterns.user_rejected

// classic/elastic remove liquidity error
if (matchPatterns(['insufficient'], error)) return t`An error occurred. Please try increasing max slippage.`
if (matchPatterns(['insufficient'], error)) return knownPatterns.insufficient

if (matchPatterns(['permit'], error)) return t`An error occurred. Invalid Permit Signature.`
if (matchPatterns(['permit'], error)) return knownPatterns.permit

if (matchPatterns(['burn amount exceeds balance'], error))
return t`Insufficient fee rewards amount, try to remove your liquidity without claiming fees for now and you can try to claim it later.`
if (matchPatterns(['burn amount exceeds balance'], error)) return knownPatterns.burn_amount_exceeds_balance

if (error === '[object Object]') return t`Something went wrong. Please try again.`
if (error === '[object Object]') return knownPatterns.object_object

return undefined
}
Expand Down
10 changes: 8 additions & 2 deletions src/utils/sentry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Deferrable } from 'ethers/lib/utils'

import { didUserReject } from 'constants/connectors/utils'

import { friendlyError } from './errorMessage'
import { friendlyError, knownPatterns } from './errorMessage'

export enum ErrorName {
LimitOrderError = 'LimitOrderError',
Expand Down Expand Up @@ -34,8 +34,14 @@ export function captureSwapError(error: TransactionError) {
? 'returnAmountIsNotEnough'
: 'other'

const level = Object.keys(knownPatterns)
.map(key => knownPatterns[key])
.includes(friendlyErrorResult)
? 'warning'
: 'error'

captureException(e, {
level: 'fatal',
level,
extra: { rawData: error.rawData },
tags: {
type: tag,
Expand Down

0 comments on commit cf21c13

Please sign in to comment.