1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00
metamask-extension/app/scripts/lib/setupSentry.js
Mark Stacey d7a5319222
Use environment variable for production Sentry DSN (#9097)
The Sentry DSN is now expected to be provided via environment variable
for production builds. The build script will fail if it is missing, and
an error will be thrown at runtime if it is missing.

The `SENTRY_DSN` environment variable has been set in CI to the old
value for `SENTRY_PROD_DSN`. We can migrate to a new DSN at some point
in the future.
2020-07-29 13:14:08 -03:00

173 lines
4.8 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_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) {
return
} 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
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
}