From ef933169866a290d4a5b960aa63df45d2cd3ce0f Mon Sep 17 00:00:00 2001 From: Sid Vishnoi <8426945+sidvishnoi@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:12:39 +0530 Subject: [PATCH] feat(ConnectWalletForm): let retry key auto-add on some errors (#642) --- src/background/services/background.ts | 3 ++- src/background/services/keyAutoAdd.ts | 12 ++++++++---- src/popup/components/ConnectWalletForm.tsx | 21 ++++++++++++++++++++- src/shared/helpers.ts | 10 +++++++--- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/background/services/background.ts b/src/background/services/background.ts index 41ee1cc9..54ccf2dc 100644 --- a/src/background/services/background.ts +++ b/src/background/services/background.ts @@ -1,6 +1,7 @@ import type { Browser } from 'webextension-polyfill'; import type { ToBackgroundMessage } from '@/shared/messages'; import { + errorWithKeyToJSON, failure, getNextOccurrence, getWalletInformation, @@ -278,7 +279,7 @@ export class Background { } catch (e) { if (isErrorWithKey(e)) { this.logger.error(message.action, e); - return failure({ key: e.key, substitutions: e.substitutions }); + return failure(errorWithKeyToJSON(e)); } if (e instanceof OpenPaymentsClientError) { this.logger.error(message.action, e.message, e.description); diff --git a/src/background/services/keyAutoAdd.ts b/src/background/services/keyAutoAdd.ts index 2a08df54..a3d2075a 100644 --- a/src/background/services/keyAutoAdd.ts +++ b/src/background/services/keyAutoAdd.ts @@ -126,10 +126,14 @@ export class KeyAutoAddService { this.browser.tabs.onRemoved.removeListener(onTabCloseListener); const { stepName, details: err } = message.payload; reject( - new ErrorWithKey('connectWalletKeyService_error_failed', [ - stepName, - isErrorWithKey(err.error) ? this.t(err.error) : err.message, - ]), + new ErrorWithKey( + 'connectWalletKeyService_error_failed', + [ + stepName, + isErrorWithKey(err.error) ? this.t(err.error) : err.message, + ], + isErrorWithKey(err.error) ? err.error : undefined, + ), ); } else if (message.action === 'PROGRESS') { // can also save progress to show in popup diff --git a/src/popup/components/ConnectWalletForm.tsx b/src/popup/components/ConnectWalletForm.tsx index 3a56f4d6..2ff01178 100644 --- a/src/popup/components/ConnectWalletForm.tsx +++ b/src/popup/components/ConnectWalletForm.tsx @@ -350,6 +350,7 @@ export const ConnectWalletForm = ({ details: errors.keyPair, whyText: t('connectWallet_error_failedAutoKeyAddWhy'), }} + retry={resetState} hideError={!errors.keyPair} text={t('connectWallet_label_publicKey')} learnMoreText={t('connectWallet_text_publicKeyLearnMore')} @@ -394,10 +395,11 @@ export const ConnectWalletForm = ({ const ManualKeyPairNeeded: React.FC<{ error: { message: string; details: null | ErrorInfo; whyText: string }; hideError?: boolean; + retry: () => Promise; text: string; learnMoreText: string; publicKey: string; -}> = ({ error, hideError, text, learnMoreText, publicKey }) => { +}> = ({ error, hideError, text, learnMoreText, publicKey, retry }) => { const ErrorDetails = () => { if (!error || !error.details) return null; return ( @@ -406,6 +408,15 @@ const ManualKeyPairNeeded: React.FC<{ {error.whyText} {error.details.message} + {canRetryAutoKeyAdd(error.details.info) && ( + + )} ); }; @@ -448,6 +459,14 @@ function isAutoKeyAddFailed(state: PopupTransientState['connect']) { return false; } +function canRetryAutoKeyAdd(err?: ErrorInfo['info']) { + if (!err) return false; + return ( + err.cause?.key === 'connectWalletKeyService_error_timeoutLogin' || + err.cause?.key === 'connectWalletKeyService_error_accountNotFound' + ); +} + const Footer: React.FC<{ text: string; learnMoreText: string; diff --git a/src/shared/helpers.ts b/src/shared/helpers.ts index 94d020c1..eb5882c1 100644 --- a/src/shared/helpers.ts +++ b/src/shared/helpers.ts @@ -74,6 +74,7 @@ export interface ErrorWithKeyLike { key: Extract; // Could be empty, but required for checking if an object follows this interface substitutions: string[]; + cause?: ErrorWithKeyLike; } export class ErrorWithKey @@ -83,8 +84,9 @@ export class ErrorWithKey constructor( public readonly key: ErrorWithKeyLike['key'], public readonly substitutions: ErrorWithKeyLike['substitutions'] = [], + public readonly cause?: ErrorWithKeyLike, ) { - super(key); + super(key, { cause }); } } @@ -96,7 +98,8 @@ export class ErrorWithKey export const errorWithKey = ( key: ErrorWithKeyLike['key'], substitutions: ErrorWithKeyLike['substitutions'] = [], -) => ({ key, substitutions }); + cause?: ErrorWithKeyLike, +) => ({ key, substitutions, cause }); export const isErrorWithKey = (err: any): err is ErrorWithKeyLike => { if (!err || typeof err !== 'object') return false; @@ -107,7 +110,8 @@ export const isErrorWithKey = (err: any): err is ErrorWithKeyLike => { }; export const errorWithKeyToJSON = (err: ErrorWithKeyLike): ErrorWithKeyLike => { - return { key: err.key, substitutions: err.substitutions }; + const { key, substitutions, cause } = err; + return { key, substitutions, cause }; }; export const success = (