1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-29 23:58:06 +01:00
metamask-extension/app/scripts/lib/setupSentry.js
2020-11-02 17:41:28 -06:00

179 lines
5.0 KiB
JavaScript

import * as Sentry from '@sentry/browser'
import { Dedupe, ExtraErrorData } from '@sentry/integrations'
import extractEthjsErrorMessage from './extractEthjsErrorMessage'
/* eslint-disable prefer-destructuring */
// Destructuring breaks the inlining of the environment variables
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
const METAMASK_ENVIRONMENT = process.env.METAMASK_ENVIRONMENT
/* eslint-enable prefer-destructuring */
const SENTRY_DSN_DEV =
'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496'
// This describes the subset of Redux state attached to errors sent to Sentry
// These properties have some potential to be useful for debugging, and they do
// not contain any identifiable information.
export const SENTRY_STATE = {
gas: true,
history: true,
metamask: {
alertEnabledness: true,
completedOnboarding: true,
connectedStatusPopoverHasBeenShown: true,
conversionDate: true,
conversionRate: true,
currentBlockGasLimit: true,
currentCurrency: true,
currentLocale: true,
customNonceValue: true,
defaultHomeActiveTabName: true,
featureFlags: true,
firstTimeFlowType: true,
forgottenPassword: true,
incomingTxLastFetchedBlocksByNetwork: true,
ipfsGateway: true,
isAccountMenuOpen: true,
isInitialized: true,
isUnlocked: true,
metaMetricsId: true,
metaMetricsSendCount: true,
nativeCurrency: true,
network: true,
nextNonce: true,
participateInMetaMetrics: true,
preferences: true,
provider: {
nickname: true,
ticker: true,
type: true,
},
seedPhraseBackedUp: true,
showRestorePrompt: true,
threeBoxDisabled: true,
threeBoxLastUpdated: true,
threeBoxSynced: true,
threeBoxSyncingAllowed: true,
unapprovedDecryptMsgCount: true,
unapprovedEncryptionPublicKeyMsgCount: true,
unapprovedMsgCount: true,
unapprovedPersonalMsgCount: true,
unapprovedTypedMessagesCount: true,
useBlockie: true,
useNonceField: true,
usePhishDetect: true,
welcomeScreenSeen: true,
},
unconnectedAccount: true,
}
export default function setupSentry({ release, getState }) {
let sentryTarget
if (METAMASK_DEBUG) {
return undefined
} else if (METAMASK_ENVIRONMENT === 'production') {
if (!process.env.SENTRY_DSN) {
throw new Error(
`Missing SENTRY_DSN environment variable in production environment`,
)
}
console.log(
`Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN`,
)
sentryTarget = process.env.SENTRY_DSN
} else {
console.log(
`Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN_DEV`,
)
sentryTarget = SENTRY_DSN_DEV
}
Sentry.init({
dsn: sentryTarget,
debug: METAMASK_DEBUG,
environment: METAMASK_ENVIRONMENT,
integrations: [new Dedupe(), new ExtraErrorData()],
release,
beforeSend: (report) => rewriteReport(report),
})
function rewriteReport(report) {
try {
// simplify certain complex error messages (e.g. Ethjs)
simplifyErrorMessages(report)
// modify report urls
rewriteReportUrls(report)
// append app state
if (getState) {
const appState = getState()
if (!report.extra) {
report.extra = {}
}
report.extra.appState = appState
}
} catch (err) {
console.warn(err)
}
return report
}
return Sentry
}
function simplifyErrorMessages(report) {
rewriteErrorMessages(report, (errorMessage) => {
// simplify ethjs error messages
let simplifiedErrorMessage = extractEthjsErrorMessage(errorMessage)
// simplify 'Transaction Failed: known transaction'
if (
simplifiedErrorMessage.indexOf(
'Transaction Failed: known transaction',
) === 0
) {
// cut the hash from the error message
simplifiedErrorMessage = 'Transaction Failed: known transaction'
}
return simplifiedErrorMessage
})
}
function rewriteErrorMessages(report, rewriteFn) {
// rewrite top level message
if (typeof report.message === 'string') {
report.message = rewriteFn(report.message)
}
// rewrite each exception message
if (report.exception && report.exception.values) {
report.exception.values.forEach((item) => {
if (typeof item.value === 'string') {
item.value = rewriteFn(item.value)
}
})
}
}
function rewriteReportUrls(report) {
// update request url
report.request.url = toMetamaskUrl(report.request.url)
// update exception stack trace
if (report.exception && report.exception.values) {
report.exception.values.forEach((item) => {
if (item.stacktrace) {
item.stacktrace.frames.forEach((frame) => {
frame.filename = toMetamaskUrl(frame.filename)
})
}
})
}
}
function toMetamaskUrl(origUrl) {
const filePath = origUrl.split(window.location.origin)[1]
if (!filePath) {
return origUrl
}
const metamaskUrl = `metamask${filePath}`
return metamaskUrl
}