From 57815188d16e0ef8d438cecb1a264afb85fea815 Mon Sep 17 00:00:00 2001 From: Petr Knetl Date: Tue, 1 Oct 2024 15:22:07 +0200 Subject: [PATCH] refactor(connect): connect error codes typing --- packages/connect/src/constants/errors.ts | 17 +++++++++++++---- packages/connect/src/events/core.ts | 5 ++++- packages/connect/src/types/params.ts | 3 ++- .../actions/settings/deviceSettingsActions.ts | 4 ++-- .../wallet/__fixtures__/discoveryActions.ts | 3 ++- .../wallet/__tests__/discoveryActions.test.ts | 4 ++-- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/connect/src/constants/errors.ts b/packages/connect/src/constants/errors.ts index b579cfc99d0..eccb6436d4d 100644 --- a/packages/connect/src/constants/errors.ts +++ b/packages/connect/src/constants/errors.ts @@ -42,21 +42,30 @@ export const ERROR_CODES = { Device_InvalidState: 'Passphrase is incorrect', // authorization error (device state comparison) Device_CallInProgress: 'Device call in progress', // thrown when trying to make another call while current is still running Device_MultipleNotSupported: 'Multiple devices are not supported', // thrown by methods which require single device -}; + + Failure_ActionCancelled: 'Action cancelled by user', + Failure_FirmwareError: 'Firmware installation failed', + Failure_UnknownCode: 'Unknown error', + Failure_PinCancelled: 'PIN cancelled', + Failure_PinMismatch: 'PIN mismatch', + Failure_WipeCodeMismatch: 'Wipe code mismatch', +} as const; + +export type ErrorCode = keyof typeof ERROR_CODES; export class TrezorError extends Error { - code: string; + code: ErrorCode; message: string; - constructor(code: string, message: string) { + constructor(code: ErrorCode, message: string) { super(message); this.code = code; this.message = message; } } -export const TypedError = (id: keyof typeof ERROR_CODES, message?: string) => +export const TypedError = (id: ErrorCode, message?: string) => new TrezorError(id, message || ERROR_CODES[id]); // serialize Error/TypeError object into payload error type (Error object/class is converted to string while sent via postMessage) diff --git a/packages/connect/src/events/core.ts b/packages/connect/src/events/core.ts index 76fe21d879d..4a53146290e 100644 --- a/packages/connect/src/events/core.ts +++ b/packages/connect/src/events/core.ts @@ -12,6 +12,7 @@ import type { import type { UiEventMessage } from './ui-request'; import type { UiResponseEvent } from './ui-response'; import type { Unsuccessful } from '../types/params'; +import { ErrorCode, TrezorError } from '../constants/errors'; export const CORE_EVENT = 'CORE_EVENT'; @@ -62,7 +63,9 @@ export const parseMessage = ({ +export const createErrorMessage = ( + error: (Error & { code?: ErrorCode }) | TrezorError, +): Unsuccessful => ({ success: false, payload: { error: error.message, diff --git a/packages/connect/src/types/params.ts b/packages/connect/src/types/params.ts index 138af6e71a8..22ad6d7455c 100644 --- a/packages/connect/src/types/params.ts +++ b/packages/connect/src/types/params.ts @@ -2,6 +2,7 @@ import { Type, TSchema, Static } from '@trezor/schema-utils'; import { DeviceState } from './device'; +import { ErrorCode } from '../constants/errors'; export interface DeviceIdentity { path?: string; @@ -38,7 +39,7 @@ export interface CommonParamsWithCoin extends CommonParams { export interface Unsuccessful { success: false; - payload: { error: string; code?: string }; + payload: { error: string; code?: ErrorCode }; } export interface Success { diff --git a/packages/suite/src/actions/settings/deviceSettingsActions.ts b/packages/suite/src/actions/settings/deviceSettingsActions.ts index daa7a594d72..38abe426527 100644 --- a/packages/suite/src/actions/settings/deviceSettingsActions.ts +++ b/packages/suite/src/actions/settings/deviceSettingsActions.ts @@ -5,7 +5,7 @@ import { FIRMWARE_MODULE_PREFIX, } from '@suite-common/wallet-core'; import * as deviceUtils from '@suite-common/suite-utils'; -import TrezorConnect from '@trezor/connect'; +import TrezorConnect, { ERRORS } from '@trezor/connect'; import { analytics, EventType } from '@trezor/suite-analytics'; import { notificationsActions } from '@suite-common/toast-notifications'; @@ -194,7 +194,7 @@ export const changeLanguage = createThunk( } else { // Different errors for desktop/Chrome/Firefox const isFetchError = - result.payload.code === 'ENOTFOUND' || + result.payload.code === ('ENOTFOUND' as ERRORS.ErrorCode) || ['Failed to fetch', 'NetworkError when attempting to fetch resource.'].includes( result.payload.error, ); diff --git a/packages/suite/src/actions/wallet/__fixtures__/discoveryActions.ts b/packages/suite/src/actions/wallet/__fixtures__/discoveryActions.ts index 1fc088aca66..de03940432b 100644 --- a/packages/suite/src/actions/wallet/__fixtures__/discoveryActions.ts +++ b/packages/suite/src/actions/wallet/__fixtures__/discoveryActions.ts @@ -1,8 +1,9 @@ import { testMocks } from '@suite-common/test-utils'; +import { ERRORS } from '@trezor/connect'; const { getSuiteDevice } = testMocks; -export const paramsError = (error: string, code?: string) => +export const paramsError = (error: string, code?: ERRORS.ErrorCode) => ({ success: false, payload: { diff --git a/packages/suite/src/actions/wallet/__tests__/discoveryActions.test.ts b/packages/suite/src/actions/wallet/__tests__/discoveryActions.test.ts index ad95842070b..a109decacea 100644 --- a/packages/suite/src/actions/wallet/__tests__/discoveryActions.test.ts +++ b/packages/suite/src/actions/wallet/__tests__/discoveryActions.test.ts @@ -17,7 +17,7 @@ import { testMocks } from '@suite-common/test-utils'; import { notificationsActions } from '@suite-common/toast-notifications'; import { DiscoveryStatus } from '@suite-common/wallet-constants'; import * as discoveryActions from '@suite-common/wallet-core'; -import TrezorConnect from '@trezor/connect'; +import TrezorConnect, { ERRORS } from '@trezor/connect'; import { configureStore, filterThunkActionTypes } from 'src/support/tests/configureStore'; import walletSettingsReducer from 'src/reducers/wallet/settingsReducer'; @@ -75,7 +75,7 @@ const setTrezorConnectFixtures = (input?: FixtureInput) => { if (code) { delete connect.error; // reset this value, it shouldn't be used in next iteration - return paramsError(error, code); + return paramsError(error, code as ERRORS.ErrorCode); } return paramsError(error);