Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions app/scripts/lib/setupSentry.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ function getClientOptions() {
// which would otherwise make the next error look like a different stack (background timers
// usually run after beforeSend finished; rapid UI captures often dedupe first).
beforeSend: (report) => rewriteReport(safeCloneReport(report)),
beforeSendTransaction: (report) =>
rewriteTransactionReport(safeCloneReport(report)),
debug: METAMASK_DEBUG,
dist: isManifestV3 ? 'mv3' : 'mv2',
dsn: sentryTarget,
Expand Down Expand Up @@ -291,8 +293,7 @@ export function beforeBreadcrumb() {
) {
return null;
}
const newBreadcrumb = removeUrlsFromBreadCrumb(breadcrumb);
return newBreadcrumb;
return breadcrumb;
};
}

Expand Down Expand Up @@ -339,7 +340,8 @@ export function shouldCreateSpanForRequest(url) {
/**
* Receives a Sentry breadcrumb object and potentially removes urls
* from its `data` property, it particular those possibly found at
* data.from, data.to and data.url
* data.from, data.to and data.url. Performs a deep address scrub for use when
* an event is about to be sent (not on every breadcrumb capture).
Comment thread
gauthierpetetin marked this conversation as resolved.
*
* @param {object} breadcrumb - A Sentry breadcrumb object: https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/
* @returns {object} A modified Sentry breadcrumb object.
Expand All @@ -365,6 +367,33 @@ export function removeUrlsFromBreadCrumb(breadcrumb) {
return breadcrumb;
}

/**
* Deep-scrubs all breadcrumbs attached to an outbound error report.
*
* @param {object} report - A Sentry event object.
*/
Comment thread
gauthierpetetin marked this conversation as resolved.
export function sanitizeBreadcrumbsInReport(report) {
if (!Array.isArray(report.breadcrumbs)) {
return;
}
report.breadcrumbs = report.breadcrumbs.map((crumb) =>
removeUrlsFromBreadCrumb(cloneDeep(crumb)),
);
}
Comment thread
gauthierpetetin marked this conversation as resolved.

/**
* Scrubs breadcrumb payloads on performance transaction events before send.
* {@link rewriteReport} handles errors via `beforeSend`; transactions use
* `beforeSendTransaction` instead.
*
* @param {object} report - A Sentry transaction event object.
* @returns {object} The modified report (same reference).
*/
export function rewriteTransactionReport(report) {
sanitizeBreadcrumbsInReport(report);
return report;
}

/**
* Receives a Sentry event object and modifies it before the error is sent to Sentry.
* Sanitizes messages/URLs and attaches app state.
Expand All @@ -383,6 +412,8 @@ export function rewriteReport(report) {
// but putting the code here as well gives public visibility to how we are handling
// privacy with respect to sentry.
sanitizeAddressesFromErrorMessages(report);
// Deep-scrub breadcrumb payloads only when an error is being sent.
sanitizeBreadcrumbsInReport(report);
// Remove addresses from other error parameters (extra, contexts).
// Done before attaching appState below so the (already masked) appState is
// not re-walked.
Expand Down
43 changes: 43 additions & 0 deletions app/scripts/lib/setupSentry.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
removeUrlsFromBreadCrumb,
rewriteReport,
rewriteTransactionReport,
shouldCreateSpanForRequest,
} from './setupSentry';

Expand Down Expand Up @@ -274,6 +275,48 @@ describe('Setup Sentry', () => {
rewriteReport(testReport);
expect(testReport.contexts.account.address).toStrictEqual('**');
});

it('removes addresses from breadcrumbs when sending an error report', () => {
const testReport = {
message: 'An error occurred',
breadcrumbs: [
{
message: 'console.error',
data: {
arguments: [
new Error(
'Failed for 0x790A8A9E9bc1C9dB991D8721a92e461Db4CfB235',
),
],
},
},
],
request: {},
};
rewriteReport(testReport);
expect(testReport.breadcrumbs[0].data.arguments[0].message).toStrictEqual(
'Failed for 0x**',
);
});
});

describe('rewriteTransactionReport', () => {
it('removes addresses from breadcrumbs when sending a transaction', () => {
const testReport = {
type: 'transaction',
transaction: 'ui.popup',
breadcrumbs: [
{
message: 'fetch',
data: {
url: 'https://api.example.com/0x790A8A9E9bc1C9dB991D8721a92e461Db4CfB235',
},
},
],
};
rewriteTransactionReport(testReport);
expect(testReport.breadcrumbs[0].data.url).toStrictEqual('');
});
});

describe('shouldCreateSpanForRequest', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default function WalletReadyAnimation() {
// Trigger the animation start when rive is loaded
useEffect(() => {
if (rive && isWasmReady && !bufferLoading && buffer) {
console.log('rive is loaded', rive);
console.log('rive is loaded');
const inputs = rive.stateMachineInputs('OnboardingLoader');
if (inputs) {
const darkToggle = inputs.find((input) => input.name === 'Dark mode');
Expand Down
Loading