Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Properly show missing vault error #30684

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

danjm
Copy link
Contributor

@danjm danjm commented Mar 3, 2025

Description

This PR updates background.js, and some related files, to ensure that an error is properly shown to the user in two cases:

  1. If the vault is missing from state when it should be present
  2. For the case of a known corrupted state error with the message "block checksum mismatch"

To achieve this, this PR adds logic to detect if the fault is missing and then throws an error, which in turn is sent via postmessage to the UI, where it is handled by a custom error screen.

Open in GitHub Codespaces

Related issues

Fixes:

Manual testing steps

  1. Install and onboard
  2. Open up the service worker console and enter this code:
chrome.storage.local.get(({ data, meta }) => {
	chrome.storage.local.set(
		{ data: {} , meta },
		() => { chrome.runtime.reload() }
        );

});
  1. After opening the UI again, you should see an error message indicating the state is corrupt

Alternatively

  1. Install and onboard
  2. Edit one of the level db files in which the extensions data is saved by deleting a single character in the file
  3. Reload the extension
  4. After opening the UI again, you should see an error message indicating the state is corrupt

Screenshots/Recordings

Screenshot from 2025-03-03 13-35-40

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Copy link
Contributor

github-actions bot commented Mar 3, 2025

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-extension-platform Extension Platform team label Mar 3, 2025
@danjm danjm marked this pull request as ready for review March 3, 2025 16:42
@danjm danjm force-pushed the display-vault-missing-error branch from 3fa2d2c to 132a5b3 Compare March 3, 2025 16:42
@danjm danjm changed the title Properly show missing vault error feat: Properly show missing vault error Mar 3, 2025
@danjm danjm mentioned this pull request Mar 3, 2025
7 tasks
Copy link
Contributor

@davidmurdoch davidmurdoch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't fully reviewed just, just trying to get some requests for changes out to you sooner rather than later.

Comment on lines +5214 to +5217
"message": "MetaMask's state file is damaged. This can happen when the browser database directs us to a state file that doesn't exist. The location of the file depends on your operating system and browser. Visit our support page for more information.\n\nYou can restore your MetaMask wallet, but doing so will erase your settings and preferences. This will also delete your state file if it still exists. You can try to back up or restore your state file manually before you decide to restore your wallet. Learn more."
},
"stateCorruptionDetectedWithBackup": {
"message": "MetaMask's state file is damaged. This usually happens when the browser database directs us to a state file that doesn't exist. The location of the file depends on your operating system and browser.\n\n A copy of your vault can be found in a secondary location. You can use it to restore your accounts, but you'll need to set up your preferences and settings again.\n\nWhen you restore your accounts, the old MetaMask files in your browser will be deleted. If you want to keep those files, back them up before you restore your accounts."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new lines here don't do anything in the rendered UI :-(

Also, the

Learn more.

Text is a bit strange, since you'd think it'd be a link but it isn't.

Comment on lines +110 to +112
const textDirection = ['ar', 'dv', 'fa', 'he', 'ku'].includes(preferredLocale)
? 'rtl'
: 'auto';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is reused twice in this file can you abstract it out to a helper funciton?

@@ -29,7 +29,7 @@ const _setupLocale = async (currentLocale) => {
return { currentLocaleMessages, enLocaleMessages };
};

export const setupLocale = memoize(_setupLocale);
export const setupErrorLocale = memoize(_setupLocale);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the rename? I think this function's return values are used for a translations all throughout the app?

Comment on lines +127 to +154
<div class="critical-error__container">
<div class="critical-error">
<div class="critical-error__icon">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="m443 342l-126-241c-16-32-40-50-65-50-26 0-50 18-66 50l-126 241c-16 30-18 60-5 83 13 23 38 36 71 36l251 0c33 0 58-13 71-36 13-23 11-53-5-83z m-206-145c0-8 6-15 15-15 8 0 14 7 14 15l0 105c0 8-6 15-14 15-9 0-15-7-15-15z m28 182c-1 1-2 2-3 3-1 0-2 1-3 1-1 1-2 1-4 2-1 0-2 0-3 0-2 0-3 0-4 0-2-1-3-1-4-2-1 0-2-1-3-1-1-1-2-2-3-3-4-4-6-9-6-15 0-5 2-11 6-15 1 0 2-1 3-2 1-1 2-2 3-2 1-1 2-1 4-1 2-1 5-1 7 0 2 0 3 0 4 1 1 0 2 1 3 2 1 1 2 2 3 2 4 4 6 10 6 15 0 6-2 11-6 15z"/>
</svg>
</div>
<div>
<p>
${
hasBackup === true
? t('stateCorruptionDetectedWithBackup')
: t('stateCorruptionDetectedNoBackup')
}
</p>
<p class="critical-error__footer">
<span>${t('unexpectedBehavior')}</span>
<a
href=${supportLink}
class="critical-error__link"
target="_blank"
rel="noopener noreferrer">
${t('sendBugReport')}
</a>
</p>
</div>
</div>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is almost this same between the two uses in this file, can you abstract out part of it (even just the svg code would be fine)

metamaskState?.data?.PreferencesController?.initializationFlags
?.vaultBackedUp;
/**
* The pattern ${errorKey === 'troubleStarting' ? t('troubleStarting') : ''}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment is for the other function

);

if (vaultHasNotYetBeenCreated === undefined && !vaultDataPresent) {
throw new Error('Data error: storage.local does not contain vault data');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this string and the use of it in STATE_CORRUPTION_ERRORS be shared? I could see someone updating the string here but not in the STATE_CORRUPTION_ERRORS array.

Comment on lines +665 to +677
const { vaultHasNotYetBeenCreated } = await browser.storage.local.get(
'vaultHasNotYetBeenCreated',
);

// read from disk
// first from preferred, async API:
const preMigrationVersionedData =
(await persistenceManager.get()) ||
migrator.generateInitialState(firstTimeState);
let preMigrationVersionedData = await persistenceManager.get();

const vaultDataPresent = Boolean(
preMigrationVersionedData?.data?.KeyringController?.vault,
);

if (vaultHasNotYetBeenCreated === undefined && !vaultDataPresent) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you refactor this to avoid the extra work in the usual case where: vault data is present. If we have vault data, we don't need to fetch vaultHasNotYetBeenCreated at all.

Ignore me if this isn't actually true, but I think it is?

if (!preMigrationVersionedData.data && !preMigrationVersionedData.meta) {
const initialState = migrator.generateInitialState(firstTimeState);
preMigrationVersionedData = {
...preMigrationVersionedData,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the need for the preMigrationVersionedData spread here? If it doesn't have a data or meta property, are there other properties we might need from it?

const html = await getStateCorruptionErrorHtml(SUPPORT_LINK, metamaskState);
container.innerHTML = html;

const button = document.getElementById('critical-error-button');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since getStateCorruptionErrorHtml function never returns an element I think this is always going to be undefined.

@@ -5210,6 +5210,12 @@
"stake": {
"message": "Stake"
},
"stateCorruptionDetectedNoBackup": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should also copy them in en_GB, right?

</p>
<p class="critical-error__footer">
<span>${t('unexpectedBehavior')}</span>
<a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an update for support link, we can have a separate ticket to integrate with the support modal
#30415

wdyt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-extension-platform Extension Platform team
Projects
Status: Needs more work from the author
Development

Successfully merging this pull request may close these issues.

4 participants