mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-01 21:57:06 +01:00
f465089c2a
Environment variables are now considered as higher-precedence than configuration by our build system. This means that if the same value is set in `.metamaskrc` and in an environment variable, the environment variable is what will be used. Previously the reverse was true, the configuration would take precedence. It is conventional for CLI tools to consider environment variables as higher precedence than configuration. This makes our build system less surprising for most people.
236 lines
6.6 KiB
JavaScript
236 lines
6.6 KiB
JavaScript
import * as Sentry from '@sentry/browser';
|
|
import { Dedupe, ExtraErrorData } from '@sentry/integrations';
|
|
|
|
import { BuildType } from '../../../shared/constants/app';
|
|
import { FilterEvents } from './sentry-filter-events';
|
|
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;
|
|
const SENTRY_DSN_DEV =
|
|
process.env.SENTRY_DSN_DEV ||
|
|
'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496';
|
|
const METAMASK_BUILD_TYPE = process.env.METAMASK_BUILD_TYPE;
|
|
const IN_TEST = process.env.IN_TEST;
|
|
/* eslint-enable prefer-destructuring */
|
|
|
|
// 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,
|
|
incomingTxLastFetchedBlockByChainId: true,
|
|
ipfsGateway: true,
|
|
isAccountMenuOpen: true,
|
|
isInitialized: true,
|
|
isUnlocked: true,
|
|
metaMetricsId: 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 }) {
|
|
if (!release) {
|
|
throw new Error('Missing release');
|
|
} else if (METAMASK_DEBUG && !IN_TEST) {
|
|
/**
|
|
* Workaround until the following issue is resolved
|
|
* https://github.com/MetaMask/metamask-extension/issues/15691
|
|
* The IN_TEST condition allows the e2e tests to run with both
|
|
* yarn start:test and yarn build:test
|
|
*/
|
|
return undefined;
|
|
}
|
|
|
|
const environment =
|
|
METAMASK_BUILD_TYPE === BuildType.main
|
|
? METAMASK_ENVIRONMENT
|
|
: `${METAMASK_ENVIRONMENT}-${METAMASK_BUILD_TYPE}`;
|
|
|
|
let sentryTarget;
|
|
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 '${environment}': SENTRY_DSN`,
|
|
);
|
|
sentryTarget = process.env.SENTRY_DSN;
|
|
} else {
|
|
console.log(
|
|
`Setting up Sentry Remote Error Reporting for '${environment}': SENTRY_DSN_DEV`,
|
|
);
|
|
sentryTarget = SENTRY_DSN_DEV;
|
|
}
|
|
|
|
/**
|
|
* A function that returns whether MetaMetrics is enabled. This should also
|
|
* return `false` if state has not yet been initialzed.
|
|
*
|
|
* @returns `true` if MetaMask's state has been initialized, and MetaMetrics
|
|
* is enabled, `false` otherwise.
|
|
*/
|
|
function getMetaMetricsEnabled() {
|
|
if (getState) {
|
|
const appState = getState();
|
|
if (!appState?.store?.metamask?.participateInMetaMetrics) {
|
|
return false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Sentry.init({
|
|
dsn: sentryTarget,
|
|
debug: METAMASK_DEBUG,
|
|
environment,
|
|
integrations: [
|
|
new FilterEvents({ getMetaMetricsEnabled }),
|
|
new Dedupe(),
|
|
new ExtraErrorData(),
|
|
],
|
|
release,
|
|
beforeSend: (report) => rewriteReport(report),
|
|
beforeBreadcrumb(breadcrumb) {
|
|
if (getState) {
|
|
const appState = getState();
|
|
if (
|
|
Object.values(appState).length &&
|
|
(!appState?.store?.metamask?.participateInMetaMetrics ||
|
|
!appState?.store?.metamask?.completedOnboarding ||
|
|
breadcrumb?.category === 'ui.input')
|
|
) {
|
|
return null;
|
|
}
|
|
} else {
|
|
return null;
|
|
}
|
|
return breadcrumb;
|
|
},
|
|
});
|
|
|
|
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;
|
|
}
|