2020-01-09 04:34:58 +01:00
|
|
|
import * as Sentry from '@sentry/browser'
|
2020-01-26 17:49:58 +01:00
|
|
|
import { Dedupe, ExtraErrorData } from '@sentry/integrations'
|
2020-01-09 04:34:58 +01:00
|
|
|
|
|
|
|
import extractEthjsErrorMessage from './extractEthjsErrorMessage'
|
|
|
|
|
2020-08-18 22:06:58 +02:00
|
|
|
const { METAMASK_DEBUG, METAMASK_ENVIRONMENT } = process.env
|
2018-10-20 08:22:50 +02:00
|
|
|
const SENTRY_DSN_DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496'
|
2018-01-17 23:59:15 +01:00
|
|
|
|
2020-07-17 17:09:38 +02:00
|
|
|
// 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 }) {
|
2018-10-20 08:22:50 +02:00
|
|
|
let sentryTarget
|
2018-01-17 23:59:15 +01:00
|
|
|
|
2020-07-28 21:59:47 +02:00
|
|
|
if (METAMASK_DEBUG) {
|
2020-08-12 21:06:57 +02:00
|
|
|
return undefined
|
2020-07-29 18:14:08 +02:00
|
|
|
} 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 {
|
2020-01-29 22:03:49 +01:00
|
|
|
console.log(`Setting up Sentry Remote Error Reporting for '${METAMASK_ENVIRONMENT}': SENTRY_DSN_DEV`)
|
2018-10-20 08:22:50 +02:00
|
|
|
sentryTarget = SENTRY_DSN_DEV
|
2018-01-17 23:59:15 +01:00
|
|
|
}
|
|
|
|
|
2018-10-20 08:22:50 +02:00
|
|
|
Sentry.init({
|
|
|
|
dsn: sentryTarget,
|
|
|
|
debug: METAMASK_DEBUG,
|
2020-01-29 22:03:49 +01:00
|
|
|
environment: METAMASK_ENVIRONMENT,
|
2020-01-26 17:49:58 +01:00
|
|
|
integrations: [
|
|
|
|
new Dedupe(),
|
|
|
|
new ExtraErrorData(),
|
|
|
|
],
|
2018-08-09 22:49:40 +02:00
|
|
|
release,
|
2018-10-20 08:22:50 +02:00
|
|
|
beforeSend: (report) => rewriteReport(report),
|
|
|
|
})
|
2018-07-19 08:22:56 +02:00
|
|
|
|
2018-11-17 01:54:55 +01:00
|
|
|
function rewriteReport (report) {
|
2018-10-20 08:22:50 +02:00
|
|
|
try {
|
|
|
|
// simplify certain complex error messages (e.g. Ethjs)
|
|
|
|
simplifyErrorMessages(report)
|
|
|
|
// modify report urls
|
|
|
|
rewriteReportUrls(report)
|
2020-07-17 17:09:38 +02:00
|
|
|
// append app state
|
|
|
|
if (getState) {
|
|
|
|
const appState = getState()
|
2020-07-18 01:31:18 +02:00
|
|
|
if (!report.extra) {
|
|
|
|
report.extra = {}
|
|
|
|
}
|
2020-07-17 17:09:38 +02:00
|
|
|
report.extra.appState = appState
|
|
|
|
}
|
2018-10-20 08:22:50 +02:00
|
|
|
} catch (err) {
|
|
|
|
console.warn(err)
|
|
|
|
}
|
2018-10-20 09:14:59 +02:00
|
|
|
return report
|
2018-10-20 08:22:50 +02:00
|
|
|
}
|
2018-03-23 23:24:32 +01:00
|
|
|
|
2018-10-20 08:22:50 +02:00
|
|
|
return Sentry
|
2018-04-30 21:10:15 +02:00
|
|
|
}
|
|
|
|
|
2018-07-03 00:49:33 +02:00
|
|
|
function simplifyErrorMessages (report) {
|
2018-05-01 01:05:01 +02:00
|
|
|
rewriteErrorMessages(report, (errorMessage) => {
|
|
|
|
// simplify ethjs error messages
|
2020-08-15 13:58:11 +02:00
|
|
|
let simplifiedErrorMessage = extractEthjsErrorMessage(errorMessage)
|
2018-05-01 01:05:01 +02:00
|
|
|
// simplify 'Transaction Failed: known transaction'
|
2020-08-15 13:58:11 +02:00
|
|
|
if (simplifiedErrorMessage.indexOf('Transaction Failed: known transaction') === 0) {
|
2018-05-01 01:05:01 +02:00
|
|
|
// cut the hash from the error message
|
2020-08-15 13:58:11 +02:00
|
|
|
simplifiedErrorMessage = 'Transaction Failed: known transaction'
|
2018-05-01 01:05:01 +02:00
|
|
|
}
|
2020-08-15 13:58:11 +02:00
|
|
|
return simplifiedErrorMessage
|
2018-05-01 01:05:01 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-07-03 00:49:33 +02:00
|
|
|
function rewriteErrorMessages (report, rewriteFn) {
|
2018-05-01 01:05:01 +02:00
|
|
|
// rewrite top level message
|
2019-11-20 01:03:20 +01:00
|
|
|
if (typeof report.message === 'string') {
|
|
|
|
report.message = rewriteFn(report.message)
|
|
|
|
}
|
2018-05-01 01:05:01 +02:00
|
|
|
// rewrite each exception message
|
2018-04-30 21:07:48 +02:00
|
|
|
if (report.exception && report.exception.values) {
|
2020-02-15 21:34:12 +01:00
|
|
|
report.exception.values.forEach((item) => {
|
2019-11-20 01:03:20 +01:00
|
|
|
if (typeof item.value === 'string') {
|
|
|
|
item.value = rewriteFn(item.value)
|
|
|
|
}
|
2018-04-30 21:07:48 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 00:49:33 +02:00
|
|
|
function rewriteReportUrls (report) {
|
2018-03-23 23:24:32 +01:00
|
|
|
// update request url
|
|
|
|
report.request.url = toMetamaskUrl(report.request.url)
|
|
|
|
// update exception stack trace
|
2018-04-29 22:46:07 +02:00
|
|
|
if (report.exception && report.exception.values) {
|
2020-02-15 21:34:12 +01:00
|
|
|
report.exception.values.forEach((item) => {
|
2020-03-12 14:51:05 +01:00
|
|
|
if (item.stacktrace) {
|
|
|
|
item.stacktrace.frames.forEach((frame) => {
|
|
|
|
frame.filename = toMetamaskUrl(frame.filename)
|
|
|
|
})
|
|
|
|
}
|
2018-03-23 23:24:32 +01:00
|
|
|
})
|
2018-04-29 22:46:07 +02:00
|
|
|
}
|
2018-03-23 23:24:32 +01:00
|
|
|
}
|
|
|
|
|
2018-07-03 00:49:33 +02:00
|
|
|
function toMetamaskUrl (origUrl) {
|
2020-04-15 19:23:27 +02:00
|
|
|
const filePath = origUrl.split(window.location.origin)[1]
|
2019-11-20 01:03:20 +01:00
|
|
|
if (!filePath) {
|
|
|
|
return origUrl
|
|
|
|
}
|
2018-03-24 02:37:41 +01:00
|
|
|
const metamaskUrl = `metamask${filePath}`
|
2018-03-23 23:24:32 +01:00
|
|
|
return metamaskUrl
|
|
|
|
}
|