From 0a4432513df5c32164656e4dcdeee4b5cff34c59 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 7 Feb 2022 15:30:37 -0330 Subject: [PATCH] captureKeyringTypesWithMissingIdentities() when 'Missing identity for address' in permissions/specifications (#13521) * captureKeyringTypesWithMissingIdentities() when 'Missing identity for address' in permissions/specifications * Fix unit tests --- .../controllers/permissions/specifications.js | 6 +++++ .../permissions/specifications.test.js | 2 ++ app/scripts/metamask-controller.js | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/app/scripts/controllers/permissions/specifications.js b/app/scripts/controllers/permissions/specifications.js index 4db3bf7ea..435079ba9 100644 --- a/app/scripts/controllers/permissions/specifications.js +++ b/app/scripts/controllers/permissions/specifications.js @@ -78,11 +78,15 @@ export const getCaveatSpecifications = ({ getIdentities }) => { * in the current MetaMask instance. * @param options.getIdentities - A function that returns the * `PreferencesController` identity objects for all Ethereum accounts in the + * @param options.captureKeyringTypesWithMissingIdentities - A function that + * captures extra error information about the "Missing identity for address" + * error. * current MetaMask instance. */ export const getPermissionSpecifications = ({ getAllAccounts, getIdentities, + captureKeyringTypesWithMissingIdentities, }) => { return { [PermissionKeys.eth_accounts]: { @@ -119,8 +123,10 @@ export const getPermissionSpecifications = ({ return accounts.sort((firstAddress, secondAddress) => { if (!identities[firstAddress]) { + captureKeyringTypesWithMissingIdentities(identities, accounts); throw new Error(`Missing identity for address: "${firstAddress}".`); } else if (!identities[secondAddress]) { + captureKeyringTypesWithMissingIdentities(identities, accounts); throw new Error( `Missing identity for address: "${secondAddress}".`, ); diff --git a/app/scripts/controllers/permissions/specifications.test.js b/app/scripts/controllers/permissions/specifications.test.js index 596172b95..dcbb69c64 100644 --- a/app/scripts/controllers/permissions/specifications.test.js +++ b/app/scripts/controllers/permissions/specifications.test.js @@ -247,6 +247,7 @@ describe('PermissionController specifications', () => { const { methodImplementation } = getPermissionSpecifications({ getIdentities, getAllAccounts, + captureKeyringTypesWithMissingIdentities: jest.fn(), })[RestrictedMethods.eth_accounts]; await expect(() => methodImplementation()).rejects.toThrow( @@ -272,6 +273,7 @@ describe('PermissionController specifications', () => { const { methodImplementation } = getPermissionSpecifications({ getIdentities, getAllAccounts, + captureKeyringTypesWithMissingIdentities: jest.fn(), })[RestrictedMethods.eth_accounts]; await expect(() => methodImplementation()).rejects.toThrow( diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 2ff28ba96..00dda02ee 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -505,6 +505,30 @@ export default class MetamaskController extends EventEmitter { getAllAccounts: this.keyringController.getAccounts.bind( this.keyringController, ), + captureKeyringTypesWithMissingIdentities: ( + identities = {}, + accounts = [], + ) => { + const accountsMissingIdentities = accounts.filter( + (address) => !identities[address], + ); + const keyringTypesWithMissingIdentities = accountsMissingIdentities.map( + (address) => + this.keyringController.getKeyringForAccount(address)?.type, + ); + + const identitiesCount = Object.keys(identities || {}).length; + + const accountTrackerCount = Object.keys( + this.accountTracker.store.getState().accounts || {}, + ).length; + + captureException( + new Error( + `Attempt to get permission specifications failed because their were ${accounts.length} accounts, but ${identitiesCount} identities, and the ${keyringTypesWithMissingIdentities} keyrings included accounts with missing identities. Meanwhile, there are ${accountTrackerCount} accounts in the account tracker.`, + ), + ); + }, }), unrestrictedMethods, });