diff --git a/packages/keyring-controller/CHANGELOG.md b/packages/keyring-controller/CHANGELOG.md index 381da0d1edb..8542b9e43c4 100644 --- a/packages/keyring-controller/CHANGELOG.md +++ b/packages/keyring-controller/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `filter` selector variant to `withKeyring` ([#8348](https://github.com/MetaMask/core/pull/8348)) - `KeyringSelector` now accepts `{ filter: ({ keyring, metadata }) => boolean }`, which selects the first keyring for which the predicate returns `true`. +- Add `isKeyringNotFoundError` ([#8351](https://github.com/MetaMask/core/pull/8351)) + - This function can be used when trying to access a non-existing keyring using `withKeyring`. ## [25.1.1] diff --git a/packages/keyring-controller/src/errors.test.ts b/packages/keyring-controller/src/errors.test.ts new file mode 100644 index 00000000000..202dfec969b --- /dev/null +++ b/packages/keyring-controller/src/errors.test.ts @@ -0,0 +1,29 @@ +import { KeyringControllerErrorMessage } from './constants'; +import { isKeyringNotFoundError, KeyringControllerError } from './errors'; + +describe('isKeyringNotFoundError', () => { + it('returns true for a KeyringControllerError with the KeyringNotFound message', () => { + const error = new KeyringControllerError( + KeyringControllerErrorMessage.KeyringNotFound, + ); + expect(isKeyringNotFoundError(error)).toBe(true); + }); + + it('returns false for a KeyringControllerError with a different message', () => { + const error = new KeyringControllerError( + KeyringControllerErrorMessage.NoKeyring, + ); + expect(isKeyringNotFoundError(error)).toBe(false); + }); + + it('returns false for a plain Error', () => { + const error = new Error(KeyringControllerErrorMessage.KeyringNotFound); + expect(isKeyringNotFoundError(error)).toBe(false); + }); + + it('returns false for a non-error value', () => { + expect(isKeyringNotFoundError('not an error')).toBe(false); + expect(isKeyringNotFoundError(null)).toBe(false); + expect(isKeyringNotFoundError(undefined)).toBe(false); + }); +}); diff --git a/packages/keyring-controller/src/errors.ts b/packages/keyring-controller/src/errors.ts index 0ef506f1d58..e590eb73b06 100644 --- a/packages/keyring-controller/src/errors.ts +++ b/packages/keyring-controller/src/errors.ts @@ -1,3 +1,5 @@ +import { KeyringControllerErrorMessage } from './constants'; + /** * Options for creating a KeyringControllerError. */ @@ -130,3 +132,20 @@ export class KeyringControllerError extends Error { return result; } } + +/** + * Returns `true` if the error is a `KeyringNotFound` error thrown by + * `KeyringController:withKeyring`. Use this to distinguish a missing keyring + * from other failures and apply fallback logic. + * + * @param error - The value to check. + * @returns Whether the error is a `KeyringNotFound` error. + */ +export function isKeyringNotFoundError( + error: unknown, +): error is KeyringControllerError { + return ( + error instanceof KeyringControllerError && + error.message === KeyringControllerErrorMessage.KeyringNotFound + ); +} diff --git a/packages/keyring-controller/src/index.ts b/packages/keyring-controller/src/index.ts index 341ad18bac3..68f49dad764 100644 --- a/packages/keyring-controller/src/index.ts +++ b/packages/keyring-controller/src/index.ts @@ -1,3 +1,4 @@ export * from './KeyringController'; export type * from './types'; export * from './errors'; +export { KeyringControllerErrorMessage } from './constants';