Skip to content

Commit 1960515

Browse files
feat(cat-voices): localised wallet errors (#3763)
* feat: localized wallet errors * fix: docs tests * fix: spelling * chore: move source code extraction to fallbackApiException * chore: use _InfoCodeError.tryFrom
1 parent ae2be38 commit 1960515

File tree

14 files changed

+325
-186
lines changed

14 files changed

+325
-186
lines changed

.config/dictionaries/project.dic

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ Embedder
122122
emiride
123123
emurgo
124124
encryptor
125+
endtemplate
125126
endfunction
126127
Eternl
127128
EUTXO

catalyst_voices/packages/internal/catalyst_voices_blocs/lib/src/registration/cubits/recover_cubit.dart

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
44
import 'package:catalyst_voices_blocs/src/registration/cubits/unlock_password_manager.dart';
5+
import 'package:catalyst_voices_blocs/src/registration/utils/logger_level_ext.dart';
56
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
67
import 'package:catalyst_voices_services/catalyst_voices_services.dart';
78
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
@@ -107,21 +108,13 @@ final class RecoverCubit extends Cubit<RecoverStateData>
107108
emit(state.copyWith(accountDetails: Optional(Success(accountDetails))));
108109

109110
return true;
110-
} on RegistrationException catch (error, stack) {
111-
_logger.severe('recover account', error, stack);
112-
113-
_recoveredAccount = null;
114-
115-
final exception = LocalizedRegistrationException.from(error);
116-
emit(state.copyWith(accountDetails: Optional(Failure(exception))));
117-
118-
return false;
119111
} catch (error, stack) {
120-
_logger.severe('recover account', error, stack);
112+
_logger.log(error.level, 'recover account', error, stack);
121113

122114
_recoveredAccount = null;
123115

124-
final exception = LocalizedException.create(error);
116+
final exception = LocalizedRegistrationException.create(error);
117+
125118
emit(state.copyWith(accountDetails: Optional(Failure(exception))));
126119

127120
return false;

catalyst_voices/packages/internal/catalyst_voices_blocs/lib/src/registration/cubits/wallet_link_cubit.dart

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:async';
22

33
import 'package:catalyst_cardano/catalyst_cardano.dart';
44
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
5+
import 'package:catalyst_voices_blocs/src/registration/utils/logger_level_ext.dart';
56
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
67
import 'package:catalyst_voices_services/catalyst_voices_services.dart';
78
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
@@ -109,31 +110,8 @@ final class WalletLinkCubit extends Cubit<WalletLinkStateData>
109110
emit(newState);
110111

111112
return true;
112-
} on WalletApiException catch (error, stackTrace) {
113-
_logger.log(
114-
error.code != WalletApiErrorCode.refused && error.code != WalletApiErrorCode.accountChange
115-
? Level.SEVERE
116-
: Level.FINER,
117-
'select wallet',
118-
error,
119-
stackTrace,
120-
);
121-
122-
_selectedWallet = null;
123-
124-
emit(
125-
state.copyWith(
126-
selectedWallet: const Optional.empty(),
127-
walletConnection: const Optional.empty(),
128-
walletSummary: const Optional.empty(),
129-
),
130-
);
131-
132-
emitError(LocalizedWalletLinkException(code: error.code));
133-
134-
return false;
135113
} catch (error, stackTrace) {
136-
_logger.severe('selectWallet', error, stackTrace);
114+
_logger.log(error.level, 'selectWallet', error, stackTrace);
137115

138116
_selectedWallet = null;
139117

@@ -145,7 +123,7 @@ final class WalletLinkCubit extends Cubit<WalletLinkStateData>
145123
),
146124
);
147125

148-
emitError(error);
126+
emitError(LocalizedRegistrationException.create(error));
149127

150128
return false;
151129
}

catalyst_voices/packages/internal/catalyst_voices_blocs/lib/src/registration/registration_cubit.dart

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:catalyst_voices_blocs/src/registration/cubits/base_profile_cubit
66
import 'package:catalyst_voices_blocs/src/registration/cubits/keychain_creation_cubit.dart';
77
import 'package:catalyst_voices_blocs/src/registration/cubits/recover_cubit.dart';
88
import 'package:catalyst_voices_blocs/src/registration/cubits/wallet_link_cubit.dart';
9+
import 'package:catalyst_voices_blocs/src/registration/utils/logger_level_ext.dart';
910
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
1011
import 'package:catalyst_voices_services/catalyst_voices_services.dart';
1112
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
@@ -173,17 +174,6 @@ final class RegistrationCubit extends Cubit<RegistrationState>
173174

174175
_progressNotifier.clear();
175176
nextStep();
176-
} on RegistrationException catch (error, stack) {
177-
_logger.severe('Submit registration failed', error, stack);
178-
179-
final exception = LocalizedRegistrationException.from(error);
180-
181-
_onRegistrationStateDataChanged(
182-
_registrationState.copyWith(
183-
canSubmitTx: Optional(Failure(exception)),
184-
isSubmittingTx: false,
185-
),
186-
);
187177
} on EmailAlreadyUsedException {
188178
emitSignal(const EmailAlreadyUsedSignal());
189179

@@ -196,9 +186,9 @@ final class RegistrationCubit extends Cubit<RegistrationState>
196186
// have to update their email in the account page.
197187
nextStep();
198188
} catch (error, stack) {
199-
_logger.severe('Submit registration failed', error, stack);
189+
_logger.log(error.level, 'Submit registration failed', error, stack);
200190

201-
const exception = LocalizedRegistrationUnknownException();
191+
final exception = LocalizedRegistrationException.create(error);
202192

203193
_onRegistrationStateDataChanged(
204194
_registrationState.copyWith(
@@ -283,12 +273,12 @@ final class RegistrationCubit extends Cubit<RegistrationState>
283273
transactionFee: Optional.of(formattedFee),
284274
),
285275
);
286-
} on RegistrationException catch (error, stackTrace) {
287-
_logger.severe('Prepare registration', error, stackTrace);
276+
} catch (error, stackTrace) {
277+
_logger.log(error.level, 'Prepare registration', error, stackTrace);
288278

289279
_transaction = null;
290280

291-
final exception = LocalizedRegistrationException.from(error);
281+
final exception = LocalizedRegistrationException.create(error);
292282

293283
_onRegistrationStateDataChanged(
294284
_registrationState.copyWith(
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'package:catalyst_cardano/catalyst_cardano.dart';
2+
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
3+
4+
extension LoggerLevelExt on Object {
5+
Level get level {
6+
final instance = this;
7+
if (instance is TxSignException && instance.code == TxSignErrorCode.userDeclined) {
8+
return Level.INFO;
9+
}
10+
if (instance is WalletApiException && instance.code == WalletApiErrorCode.refused) {
11+
return Level.INFO;
12+
}
13+
if (instance is WalletApiException && instance.code == WalletApiErrorCode.accountChange) {
14+
return Level.INFO;
15+
}
16+
if (instance is WalletDataSignException &&
17+
instance.code == WalletDataSignErrorCode.userDeclined) {
18+
return Level.INFO;
19+
}
20+
21+
return Level.SEVERE;
22+
}
23+
}

catalyst_voices/packages/internal/catalyst_voices_localization/lib/l10n/intl_en.arb

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,22 +1296,76 @@
12961296
"@errorValidationTokenNotParsed": {
12971297
"description": "A validation error when user enters input which cannot be parsed into token value."
12981298
},
1299-
"errorWalletLinkAccountChange": "Wallet account change",
1299+
"errorWalletLinkAccountChange": "Wallet account has changed.",
13001300
"@errorWalletLinkAccountChange": {
13011301
"description": "Error message shown when wallet account has changed"
13021302
},
1303-
"errorWalletLinkInternalError": "Wallet authorisation internal error",
1303+
"errorWalletLinkInternalError": "Wallet error occurred during execution of this API call.",
13041304
"@errorWalletLinkInternalError": {
13051305
"description": "Error message shown when internal error occurs during wallet authorization"
13061306
},
1307-
"errorWalletLinkInvalidRequest": "Wallet authorisation invalid request",
1307+
"errorWalletLinkInvalidRequest": "Wallet inputs do not conform to this spec or are otherwise invalid.",
13081308
"@errorWalletLinkInvalidRequest": {
13091309
"description": "Error message shown when wallet authorization request is invalid"
13101310
},
1311-
"errorWalletLinkRefused": "Wallet authorisation failed",
1311+
"errorWalletLinkInvalidRequestCode": "Wallet request failed with code {code}.",
1312+
"@errorWalletLinkInvalidRequestCode": {
1313+
"description": "Error message shown when wallet authorization request is invalid",
1314+
"placeholders": {
1315+
"code": {
1316+
"type": "int"
1317+
}
1318+
}
1319+
},
1320+
"errorWalletLinkRefused": "The wallet request was refused due to lack of access.",
13121321
"@errorWalletLinkRefused": {
13131322
"description": "Error message shown when wallet authorization is refused"
13141323
},
1324+
"errorWalletTxSendRefused": "Wallet refuses to send the tx (could be rate limiting).",
1325+
"@errorWalletTxSendRefused": {
1326+
"description": "Error message shown when wallet throws TxSend exception"
1327+
},
1328+
"errorWalletTxSendFailure": "Wallet could not send the tx.",
1329+
"@errorWalletTxSendFailure": {
1330+
"description": "Error message shown when wallet throws TxSend exception"
1331+
},
1332+
"errorWalletTxSignProofGeneration": "Wallet was unable to sign the transaction.",
1333+
"@errorWalletTxSignProofGeneration": {
1334+
"description": "Error message shown when wallet throws TxSign exception"
1335+
},
1336+
"errorWalletTxSignUserDeclined": "Transaction declined.",
1337+
"@errorWalletTxSignUserDeclined": {
1338+
"description": "Error message shown when wallet throws TxSign exception"
1339+
},
1340+
"errorWalletTxSignDepreciatedCertificate": "Transaction contains depreciated certificate.",
1341+
"@errorWalletTxSignDepreciatedCertificate": {
1342+
"description": "Error message shown when wallet throws TxSign exception"
1343+
},
1344+
"errorWalletDataSignProofGeneration": "Wallet was unable to sign the data.",
1345+
"@errorWalletDataSignProofGeneration": {
1346+
"description": "Error message shown when wallet throws DataSign exception"
1347+
},
1348+
"errorWalletDataSignAddressNotPk": "Wallet was unable to sign the data because of address format.",
1349+
"@errorWalletDataSignAddressNotPk": {
1350+
"description": "Error message shown when wallet throws DataSign exception"
1351+
},
1352+
"errorWalletDataSignUserDeclined": "Transaction declined.",
1353+
"@errorWalletDataSignUserDeclined": {
1354+
"description": "Error message shown when wallet throws DataSign exception"
1355+
},
1356+
"errorWalletPaginationMaxSize": "Wallet pagination max size({maxSize}) exceeded.",
1357+
"@errorWalletPaginationMaxSize": {
1358+
"description": "Error message shown when wallet throws DataSign exception",
1359+
"placeholders": {
1360+
"maxSize": {
1361+
"type": "int"
1362+
}
1363+
}
1364+
},
1365+
"errorCardanoWalletUnknown": "Wallet failed unexpectedly.",
1366+
"@errorCardanoWalletUnknown": {
1367+
"description": "Generic wallet exception"
1368+
},
13151369
"eternlWallet": "Eternl Wallet",
13161370
"@eternlWallet": {
13171371
"description": "Name of the eternl wallet"
@@ -2854,10 +2908,6 @@
28542908
"@registrationSeedPhraseNotFound": {
28552909
"description": "Error message shown when attempting to register or recover account but seed phrase was not found"
28562910
},
2857-
"registrationTransactionFailed": "Transaction failed",
2858-
"@registrationTransactionFailed": {
2859-
"description": "Indicates an error when submitting a registration transaction failed."
2860-
},
28612911
"registrationTransactionFeeDescription": "The creation of a Catalyst account costs, a transaction fee of (0,21 {currency}), be sure your wallet has a minimum of {money}.",
28622912
"@registrationTransactionFeeDescription": {
28632913
"description": "Description for the registration transaction fee",

catalyst_voices/packages/internal/catalyst_voices_models/lib/src/registration/exception/registration_exception.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,3 @@ final class RegistrationRecoverKeychainNotFoundException extends RegistrationExc
6868
@override
6969
String toString() => 'RegistrationRecoverKeychainNotFoundException';
7070
}
71-
72-
/// An exception thrown when attempting to register and the transaction fails.
73-
final class RegistrationTransactionException extends RegistrationException {
74-
const RegistrationTransactionException();
75-
76-
@override
77-
String toString() => 'RegistrationTransactionException';
78-
}
79-
80-
/// An exception thrown when attempting to register and the transaction fails.
81-
final class RegistrationUnknownException extends RegistrationException {
82-
const RegistrationUnknownException();
83-
84-
@override
85-
String toString() => 'RegistrationUnknownException';
86-
}

catalyst_voices/packages/internal/catalyst_voices_repositories/test/fixture/voices_document_templates.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ class VoicesDocumentsTemplates {
2323
static Future<Directory> _getDocsRoot() async {
2424
var dir = Directory.current;
2525

26+
final blacklisted = ['catalyst_voices'];
27+
2628
while (true) {
27-
final list = dir.listSync();
29+
final skip = blacklisted.any((path) => dir.path.endsWith(path));
30+
final list = skip ? <FileSystemEntity>[] : dir.listSync();
2831
final docs = list.firstWhereOrNull((e) => e.path.endsWith('/docs'));
2932
if (docs != null) {
3033
return Directory(docs.path);

0 commit comments

Comments
 (0)