diff --git a/app/scripts/background.js b/app/scripts/background.js index 7b45cdfd5..69cf65964 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -88,7 +88,7 @@ const metamaskInternalProcessHash = { const metamaskBlockedPorts = ['trezor-connect']; -log.setDefaultLevel(process.env.METAMASK_DEBUG ? 'debug' : 'info'); +log.setLevel(process.env.METAMASK_DEBUG ? 'debug' : 'info', false); const platform = new ExtensionPlatform(); const notificationManager = new NotificationManager(); diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index 3c1415e53..12de298bd 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -744,6 +744,13 @@ class FixtureBuilder { return this; } + withBadPreferencesControllerState() { + merge(this.fixture.data, { + PreferencesController: 5, + }); + return this; + } + withTokensControllerERC20() { merge(this.fixture.data.TokensController, { tokens: [ diff --git a/test/e2e/tests/errors.spec.js b/test/e2e/tests/errors.spec.js index 36f1921b3..5c557b256 100644 --- a/test/e2e/tests/errors.spec.js +++ b/test/e2e/tests/errors.spec.js @@ -124,6 +124,18 @@ describe('Sentry errors', function () { }); } + async function mockSentryInvariantMigrationError(mockServer) { + return await mockServer + .forPost('https://sentry.io/api/0000000/envelope/') + .withBodyIncluding('typeof state.PreferencesController is number') + .thenCallback(() => { + return { + statusCode: 200, + json: {}, + }; + }); + } + async function mockSentryTestError(mockServer) { return await mockServer .forPost('https://sentry.io/api/0000000/envelope/') @@ -307,6 +319,54 @@ describe('Sentry errors', function () { ); }); + it('should capture migration log breadcrumbs when there is an invariant state error in a migration', async function () { + await withFixtures( + { + fixtures: { + ...new FixtureBuilder() + .withMetaMetricsController({ + metaMetricsId: 'fake-metrics-id', + participateInMetaMetrics: true, + }) + .withBadPreferencesControllerState() + .build(), + }, + ganacheOptions, + title: this.test.title, + failOnConsoleError: false, + testSpecificMock: mockSentryInvariantMigrationError, + }, + async ({ driver, mockedEndpoint }) => { + await driver.navigate(); + + // Wait for Sentry request + await driver.wait(async () => { + const isPending = await mockedEndpoint.isPending(); + return isPending === false; + }, 3000); + + const [mockedRequest] = await mockedEndpoint.getSeenRequests(); + const mockTextBody = mockedRequest.body.text.split('\n'); + const mockJsonBody = JSON.parse(mockTextBody[2]); + const breadcrumbs = mockJsonBody?.breadcrumbs ?? []; + const migrationLogBreadcrumbs = breadcrumbs.filter((breadcrumb) => { + return breadcrumb.message?.match(/Running migration \d+/u); + }); + const migrationLogMessages = migrationLogBreadcrumbs.map( + (breadcrumb) => + breadcrumb.message.match(/(Running migration \d+)/u)[1], + ); + const firstMigrationLog = migrationLogMessages[0]; + const lastMigrationLog = + migrationLogMessages[migrationLogMessages.length - 1]; + + assert.equal(migrationLogMessages.length, 8); + assert.equal(firstMigrationLog, 'Running migration 75'); + assert.equal(lastMigrationLog, 'Running migration 82'); + }, + ); + }); + it('should send error events in UI', async function () { await withFixtures( { diff --git a/ui/index.js b/ui/index.js index de1432a80..208006de1 100644 --- a/ui/index.js +++ b/ui/index.js @@ -27,7 +27,7 @@ import Root from './pages'; import txHelper from './helpers/utils/tx-helper'; import { _setBackgroundConnection } from './store/action-queue'; -log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn'); +log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn', false); let reduxStore;