mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
e8b33fb7c8
The state snapshot that was attached to Sentry errors was removed recently in #8794 because it had become too large. The snapshot has now been restored and reduced in size. A utility function has been written to reduce the state object to just the requested properties. This seemed safer than filtering out state that is known to be large or to contain identifiable information. This is not a great solution, as now knowledge about the state shape resides in this large constant, but it will suffice for now. I am hopeful that we can decorate our controllers with this metadata in the future instead, as part of the upcoming background controller refactor. A separate `getSentryState` global function has been added to get the reduced state, so that the old `getCleanAppState` function that we used to use could remain unchanged. It's still useful to get that full state copy while debugging, and in e2e tests.
166 lines
4.6 KiB
JavaScript
166 lines
4.6 KiB
JavaScript
import * as Sentry from '@sentry/browser'
|
|
import { Dedupe, ExtraErrorData } from '@sentry/integrations'
|
|
|
|
import extractEthjsErrorMessage from './extractEthjsErrorMessage'
|
|
|
|
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
|
|
const METAMASK_ENVIRONMENT = process.env.METAMASK_ENVIRONMENT
|
|
const SENTRY_DSN_PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505'
|
|
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,
|
|
settings: {
|
|
chainId: true,
|
|
ticker: true,
|
|
nickname: 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 || process.env.IN_TEST) {
|
|
console.log(`Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN_DEV`)
|
|
sentryTarget = SENTRY_DSN_DEV
|
|
} else {
|
|
console.log(`Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN_PROD`)
|
|
sentryTarget = SENTRY_DSN_PROD
|
|
}
|
|
|
|
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()
|
|
report.extra.appState = appState
|
|
}
|
|
} catch (err) {
|
|
console.warn(err)
|
|
}
|
|
return report
|
|
}
|
|
|
|
return Sentry
|
|
}
|
|
|
|
function simplifyErrorMessages (report) {
|
|
rewriteErrorMessages(report, (errorMessage) => {
|
|
// simplify ethjs error messages
|
|
errorMessage = extractEthjsErrorMessage(errorMessage)
|
|
// simplify 'Transaction Failed: known transaction'
|
|
if (errorMessage.indexOf('Transaction Failed: known transaction') === 0) {
|
|
// cut the hash from the error message
|
|
errorMessage = 'Transaction Failed: known transaction'
|
|
}
|
|
return errorMessage
|
|
})
|
|
}
|
|
|
|
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
|
|
}
|