diff --git a/starport_template/lib/entities/error_details.dart b/starport_template/lib/entities/error_details.dart new file mode 100644 index 00000000..478db966 --- /dev/null +++ b/starport_template/lib/entities/error_details.dart @@ -0,0 +1,26 @@ +import 'package:equatable/equatable.dart'; + +class CosmosErrorDetails extends Equatable { + const CosmosErrorDetails({ + required this.error, + this.stackTrace, + }); + + factory CosmosErrorDetails.empty() => const CosmosErrorDetails(error: ''); + + final dynamic error; + final StackTrace? stackTrace; + + @override + List get props => [ + error, + stackTrace ?? '', + ]; + + @override + String toString() => ''' + Error[ + error: $error, + stackTrace: $stackTrace + ]'''; +} diff --git a/starport_template/lib/pages/create_account_page.dart b/starport_template/lib/pages/create_account_page.dart index ccc22804..62c8c9cc 100644 --- a/starport_template/lib/pages/create_account_page.dart +++ b/starport_template/lib/pages/create_account_page.dart @@ -5,6 +5,7 @@ import 'package:cosmos_utils/cosmos_utils.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; +import 'package:starport_template/entities/error_details.dart'; import 'package:starport_template/pages/assets_portfolio_page.dart'; import 'package:starport_template/pages/back_up_account_page.dart'; import 'package:starport_template/pages/backup_later_bottom_sheet.dart'; @@ -44,6 +45,8 @@ class _CreateAccountPageState extends State { bool get isAccountImportingError => StarportApp.accountsStore.isAccountImportingError; + CosmosErrorDetails get errorDetails => StarportApp.accountsStore.errorDetails; + @override void initState() { super.initState(); @@ -122,8 +125,8 @@ class _CreateAccountPageState extends State { } Widget _errorUI() { - return const Center( - child: Text('Error!'), + return ErrorWidget.withDetails( + error: FlutterError(errorDetails.toString()), ); } @@ -193,6 +196,7 @@ class _CreateAccountPageState extends State { ..add(DiagnosticsProperty('isLoading', isLoading)) ..add(DiagnosticsProperty('isAuthenticating', isAuthenticating)) ..add(DiagnosticsProperty('isAccountImportingError', isAccountImportingError)) - ..add(DiagnosticsProperty('isError', isError)); + ..add(DiagnosticsProperty('isError', isError)) + ..add(DiagnosticsProperty('errorDetails', errorDetails)); } } diff --git a/starport_template/lib/starport_app.dart b/starport_template/lib/starport_app.dart index 66b0d61e..a6c510ca 100644 --- a/starport_template/lib/starport_app.dart +++ b/starport_template/lib/starport_app.dart @@ -1,6 +1,6 @@ import 'package:alan/alan.dart'; import 'package:cosmos_auth/auth/cosmos_auth.dart'; -import 'package:cosmos_ui_components/cosmos_theme.dart'; +import 'package:cosmos_ui_components/cosmos_ui_components.dart'; import 'package:cosmos_utils/cosmos_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -34,6 +34,7 @@ class StarportApp extends StatelessWidget { brightness: themeStore.isDarkTheme ? Brightness.dark : Brightness.light, child: Builder( builder: (context) { + setErrorBuilder(context); return MaterialApp( title: 'Starport template', theme: CosmosTheme.of(context).buildFlutterTheme(), @@ -44,4 +45,48 @@ class StarportApp extends StatelessWidget { ), ); } + + void setErrorBuilder(BuildContext context) { + ErrorWidget.builder = (errorDetails) { + return Material( + color: Colors.white, + child: Center( + child: Padding( + padding: const EdgeInsets.all(24), + child: ListView( + children: [ + const Text( + 'Error!', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + Text( + errorDetails.toString(), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.w400, + ), + ), + Row( + children: [ + CosmosElevatedButton( + text: 'Take me back', + onTap: () => Navigator.pop(context), + textColor: Colors.black, + ), + CosmosTextButton( + text: 'Back', + onTap: () => Navigator.of(context).pop(), + ), + ], + ), + ], + ), + ), + ), + ); + }; + } } diff --git a/starport_template/lib/stores/accounts_store.dart b/starport_template/lib/stores/accounts_store.dart index 270732fb..9b488a89 100644 --- a/starport_template/lib/stores/accounts_store.dart +++ b/starport_template/lib/stores/accounts_store.dart @@ -4,6 +4,7 @@ import 'package:mobx/mobx.dart'; import 'package:starport_template/app_config.dart'; import 'package:starport_template/entities/account_additional_data.dart'; import 'package:starport_template/entities/balance.dart'; +import 'package:starport_template/entities/error_details.dart'; import 'package:starport_template/entities/import_account_form_data.dart'; import 'package:starport_template/utils/cosmos_balances.dart'; import 'package:starport_template/utils/token_sender.dart'; @@ -32,6 +33,7 @@ class AccountsStore { final Observable _isBalancesLoadingError = Observable(false); final Observable _isRenamingAccount = Observable(false); final Observable _isSendingMoney = Observable(false); + final Observable _errorDetails = Observable(CosmosErrorDetails.empty()); final ObservableList balancesList = ObservableList(); final Observable loadAccountsFailure = Observable(null); @@ -78,6 +80,10 @@ class AccountsStore { set isMnemonicCreatingError(bool val) => Action(() => _isMnemonicCreatingError.value = val)(); + CosmosErrorDetails get errorDetails => _errorDetails.value; + + set errorDetails(CosmosErrorDetails val) => Action(() => _errorDetails.value = val)(); + bool get isMnemonicCreating => _isMnemonicCreating.value; set isMnemonicCreating(bool val) => Action(() => _isMnemonicCreating.value = val)(); @@ -202,6 +208,7 @@ class AccountsStore { return result.fold( (fail) { logError(fail); + errorDetails = CosmosErrorDetails(error: fail); isAccountImportingError = true; return null; }, @@ -234,6 +241,7 @@ class AccountsStore { await getBalances(selectedAccount.publicAddress); } catch (ex, stack) { logError(ex, stack); + errorDetails = CosmosErrorDetails(error: ex, stackTrace: stack); isSendMoneyError = true; } isSendMoneyLoading = false; @@ -271,6 +279,7 @@ class AccountsStore { mnemonic = await generateMnemonic(); } catch (ex, stack) { logError(ex, stack); + errorDetails = CosmosErrorDetails(error: ex, stackTrace: stack); isMnemonicCreatingError = true; } isMnemonicCreating = false;