1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00
metamask-extension/app/scripts/lib/network-store.js
Mark Stacey 9cfa9ba6b0
Fix pre-initialization UI error state capture ()
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.
2023-08-18 16:32:28 -02:30

93 lines
2.2 KiB
JavaScript

import log from 'loglevel';
import getFetchWithTimeout from '../../../shared/modules/fetch-with-timeout';
const fetchWithTimeout = getFetchWithTimeout();
const FIXTURE_SERVER_HOST = 'localhost';
const FIXTURE_SERVER_PORT = 12345;
const FIXTURE_SERVER_URL = `http://${FIXTURE_SERVER_HOST}:${FIXTURE_SERVER_PORT}/state.json`;
/**
* A read-only network-based storage wrapper
*/
export default class ReadOnlyNetworkStore {
constructor() {
this._initialized = false;
this._initializing = this._init();
this._state = undefined;
this.mostRecentRetrievedState = null;
}
/**
* Declares this store as compatible with the current browser
*/
isSupported = true;
/**
* Initializes by loading state from the network
*/
async _init() {
try {
const response = await fetchWithTimeout(FIXTURE_SERVER_URL);
if (response.ok) {
this._state = await response.json();
}
} catch (error) {
log.debug(`Error loading network state: '${error.message}'`);
} finally {
this._initialized = true;
}
}
/**
* Returns state
*
* @returns {Promise<object>}
*/
async get() {
if (!this._initialized) {
await this._initializing;
}
// Delay setting this until after the first read, to match the
// behavior of the local store.
if (!this.mostRecentRetrievedState) {
this.mostRecentRetrievedState = this._state;
}
return this._state;
}
/**
* Set metadata/version state
*
* @param {object} metadata - The metadata/version data to set
*/
setMetadata(metadata) {
this.metadata = metadata;
}
/**
* Set state
*
* @param {object} state - The state to set
*/
async set(state) {
if (!this.isSupported) {
throw new Error(
'Metamask- cannot persist state to local store as this browser does not support this action',
);
}
if (!state) {
throw new Error('MetaMask - updated state is missing');
}
if (!this.metadata) {
throw new Error(
'MetaMask - metadata must be set on instance of ExtensionStore before calling "set"',
);
}
if (!this._initialized) {
await this._initializing;
}
this._state = { data: state, meta: this._metadata };
}
}