mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
9cfa9ba6b0
In the case where an error is thrown in the UI before initialization has finished, we aren't capturing the application state correctly for Sentry errors. We had a test case for this, but the test case was broken due to a mistake in how the `network-store` was setup (it was not matching the behavior of the real `local-tstore` module). The pre-initialization state capture logic was updated to rely solely upon the `localStore` instance used by Sentry to determine whether the user had opted-in to metrics or not. This simplifies the logic a great deal, removing the need for the `getMostRecentPersistedState` state hook. It also ensures that state is captured corretly pre- initialization in both the background and UI.
69 lines
2.1 KiB
JavaScript
69 lines
2.1 KiB
JavaScript
import { maskObject } from '../../../shared/modules/object.utils';
|
|
import ExtensionPlatform from '../platforms/extension';
|
|
import LocalStore from './local-store';
|
|
import ReadOnlyNetworkStore from './network-store';
|
|
import { SENTRY_BACKGROUND_STATE } from './setupSentry';
|
|
|
|
const platform = new ExtensionPlatform();
|
|
|
|
// This instance of `localStore` is used by Sentry to get the persisted state
|
|
const sentryLocalStore = process.env.IN_TEST
|
|
? new ReadOnlyNetworkStore()
|
|
: new LocalStore();
|
|
|
|
/**
|
|
* Get the persisted wallet state.
|
|
*
|
|
* @returns The persisted wallet state.
|
|
*/
|
|
globalThis.stateHooks.getPersistedState = async function () {
|
|
return await sentryLocalStore.get();
|
|
};
|
|
|
|
const persistedStateMask = {
|
|
data: SENTRY_BACKGROUND_STATE,
|
|
meta: {
|
|
version: true,
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Get a state snapshot to include with Sentry error reports. This uses the
|
|
* persisted state pre-initialization, and the in-memory state post-
|
|
* initialization. In both cases the state is anonymized.
|
|
*
|
|
* @returns A Sentry state snapshot.
|
|
*/
|
|
globalThis.stateHooks.getSentryState = function () {
|
|
const sentryState = {
|
|
browser: window.navigator.userAgent,
|
|
version: platform.getVersion(),
|
|
};
|
|
// If `getSentryAppState` is set, it implies that initialization has completed
|
|
if (globalThis.stateHooks.getSentryAppState) {
|
|
return {
|
|
...sentryState,
|
|
state: globalThis.stateHooks.getSentryAppState(),
|
|
};
|
|
} else if (
|
|
// This is truthy if Sentry has retrieved state at least once already. This
|
|
// should always be true because Sentry calls `getPersistedState` during
|
|
// error processing (before this function is called) if `getSentryAppState`
|
|
// hasn't been set yet.
|
|
sentryLocalStore.mostRecentRetrievedState
|
|
) {
|
|
return {
|
|
...sentryState,
|
|
persistedState: maskObject(
|
|
sentryLocalStore.mostRecentRetrievedState,
|
|
persistedStateMask,
|
|
),
|
|
};
|
|
}
|
|
// This branch means that local storage has not yet been read, so we have
|
|
// no choice but to omit the application state.
|
|
// This should be unreachable, unless an error was encountered during error
|
|
// processing.
|
|
return sentryState;
|
|
};
|