From 38da6e73d4d6a1ca5a7c13698c58475f70f22919 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 23 Nov 2022 18:06:09 +0200 Subject: [PATCH 01/13] Wrap app in zone guard --- lib/main.dart | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 3cd5679b3..193240518 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -42,9 +42,16 @@ final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); Future main() async { - try { + + await runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); + // FlutterError.onError = ; + + // Isolate.current.addErrorListener(RawReceivePort((pair) async { + // final List errorAndStacktrace = pair; + // }).sendPort); + final appDir = await getApplicationDocumentsDirectory(); await Hive.close(); Hive.init(appDir.path); @@ -130,7 +137,7 @@ Future main() async { secureStorage: secureStorage, initialMigrationVersion: 17); runApp(App()); - } catch (e, stacktrace) { + }, (error, stackTrace) { runApp(MaterialApp( debugShowCheckedModeBanner: true, home: Scaffold( @@ -138,10 +145,10 @@ Future main() async { margin: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20), child: Text( - 'Error:\n${e.toString()}\nStacktrace: $stacktrace', + 'Error:\n${error.toString()}\nStacktrace: $stackTrace', style: TextStyle(fontSize: 22), ))))); - } + }); } Future initialSetup( From 68c20641b959844bb5495e48126190bfb69d8c05 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 23 Nov 2022 23:02:18 +0200 Subject: [PATCH 02/13] Save exceptions locally --- lib/main.dart | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 193240518..541415f13 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,7 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:isolate'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/buy/order.dart'; @@ -46,11 +49,24 @@ Future main() async { await runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); - // FlutterError.onError = ; + FlutterError.onError = (errorDetails) { + _saveException(errorDetails.exception.toString(), errorDetails.stack); + }; - // Isolate.current.addErrorListener(RawReceivePort((pair) async { - // final List errorAndStacktrace = pair; - // }).sendPort); + PlatformDispatcher.instance.onError = (error, stack) { + _saveException(error.toString(), stack); + return true; + }; + + Isolate.current.addErrorListener(RawReceivePort((pair) async { + final errorAndStacktrace = pair as List; + _saveException( + errorAndStacktrace.first, + errorAndStacktrace.last == null + ? null + : StackTrace.fromString(errorAndStacktrace.last!), + ); + }).sendPort); final appDir = await getApplicationDocumentsDirectory(); await Hive.close(); @@ -151,6 +167,17 @@ Future main() async { }); } +void _saveException(String? error, StackTrace? stackTrace) async { + final file = File('/error.txt'); + final exception = { + "${DateTime.now()}": { + "error": error, + "stackTrace": stackTrace.toString(), + } + }; + await file.writeAsString(jsonEncode(exception), mode: FileMode.append); +} + Future initialSetup( {required SharedPreferences sharedPreferences, required Box nodes, From 34746c31c8848fa17ec54152b55d09e95aebf72d Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Thu, 24 Nov 2022 16:27:29 +0200 Subject: [PATCH 03/13] Save exceptions to local file --- lib/main.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/main.dart b/lib/main.dart index 541415f13..ba5b78e44 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -154,6 +154,7 @@ Future main() async { initialMigrationVersion: 17); runApp(App()); }, (error, stackTrace) { + _saveException(error.toString(), stackTrace); runApp(MaterialApp( debugShowCheckedModeBanner: true, home: Scaffold( From 7b99e409a9e0c9a4eba92698557923e1b251eecb Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Fri, 25 Nov 2022 18:59:47 +0200 Subject: [PATCH 04/13] Send error file via email --- lib/main.dart | 67 +++++++++++++++++------- lib/src/screens/failure_page.dart | 87 +++++++++++++++++++++++++++++++ pubspec_base.yaml | 1 + 3 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 lib/src/screens/failure_page.dart diff --git a/lib/main.dart b/lib/main.dart index ba5b78e44..4ffb168f6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,9 +5,12 @@ import 'dart:isolate'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/buy/order.dart'; +import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; +import 'package:cake_wallet/src/screens/failure_page.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; +import 'package:cake_wallet/themes/theme_list.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -50,24 +53,28 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (errorDetails) { + print("@@@@@@@@@@@@@@@"); + print("FlutterError.onError"); + print(errorDetails); _saveException(errorDetails.exception.toString(), errorDetails.stack); }; + ErrorWidget.builder = (errorDetails) { + return FailurePage( + error: errorDetails.exception.toString(), + stackTrace: errorDetails.stack, + ); + }; + + /// A callback that is invoked when an unhandled error occurs in the root + /// isolate. PlatformDispatcher.instance.onError = (error, stack) { + print("@@@@@@@@@@@@@@@"); + print("PlatformDispatcher.instance.onError"); _saveException(error.toString(), stack); return true; }; - Isolate.current.addErrorListener(RawReceivePort((pair) async { - final errorAndStacktrace = pair as List; - _saveException( - errorAndStacktrace.first, - errorAndStacktrace.last == null - ? null - : StackTrace.fromString(errorAndStacktrace.last!), - ); - }).sendPort); - final appDir = await getApplicationDocumentsDirectory(); await Hive.close(); Hive.init(appDir.path); @@ -153,29 +160,49 @@ Future main() async { secureStorage: secureStorage, initialMigrationVersion: 17); runApp(App()); - }, (error, stackTrace) { + }, (error, stackTrace) async { _saveException(error.toString(), stackTrace); - runApp(MaterialApp( + final sharedPreferences = await SharedPreferences.getInstance(); + final theme = ThemeList.deserialize( + raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? 0); + + final savedLanguageCode = + sharedPreferences.getString(PreferencesKey.currentLanguageCode) ?? + await LanguageService.localeDetection(); + runApp( + MaterialApp( debugShowCheckedModeBanner: true, + theme: theme.themeData, + localizationsDelegates: [ + S.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + supportedLocales: S.delegate.supportedLocales, + locale: Locale(savedLanguageCode), home: Scaffold( - body: Container( - margin: - EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20), - child: Text( - 'Error:\n${error.toString()}\nStacktrace: $stackTrace', - style: TextStyle(fontSize: 22), - ))))); + body: FailurePage( + error: error.toString(), + stackTrace: stackTrace, + ), + ), + ), + ); }); } void _saveException(String? error, StackTrace? stackTrace) async { - final file = File('/error.txt'); + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); final exception = { "${DateTime.now()}": { "error": error, "stackTrace": stackTrace.toString(), } }; + await file.writeAsString(jsonEncode(exception), mode: FileMode.append); } diff --git a/lib/src/screens/failure_page.dart b/lib/src/screens/failure_page.dart new file mode 100644 index 000000000..ea3d75fcb --- /dev/null +++ b/lib/src/screens/failure_page.dart @@ -0,0 +1,87 @@ +import 'dart:io'; + +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/src/widgets/primary_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mailer/flutter_mailer.dart'; +import 'package:path_provider/path_provider.dart'; + +class FailurePage extends StatelessWidget { + final String? error; + final StackTrace? stackTrace; + + FailurePage({Key? key, this.error, this.stackTrace}); + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + return Scaffold( + backgroundColor: Colors.grey.shade400, + body: Center( + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: MediaQuery.of(context).size.width * 0.2), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon( + Icons.warning, + color: theme.errorColor, + size: 50, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Text( + "Oops, we got some error.", + style: theme.textTheme.headline1?.copyWith(fontSize: 20), + ), + ), + Text( + "Please send crash report to our support team to make the application better.", + textAlign: TextAlign.center, + style: theme.textTheme.headline1?.copyWith(fontSize: 16), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: PrimaryButton( + onPressed: _sendExceptionFile, + text: S.of(context).send, + textColor: Colors.white, + color: theme.accentTextTheme.bodyText1!.color!, + ), + ), + PrimaryButton( + onPressed: () { + }, + text: "Don't Send", + color: Theme.of(context).accentTextTheme.caption!.color!, + textColor: + Theme.of(context).primaryTextTheme.headline6!.color!, + ), + ], + ), + ), + ), + ); + } + + void _sendExceptionFile() async { + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); + + print(file.readAsStringSync()); + + final MailOptions mailOptions = MailOptions( + subject: 'Mobile App Issue', + recipients: ['support@cakewallet.com'], + attachments: [file.path], + ); + + await FlutterMailer.send(mailOptions); + + // clear file content + // file.writeAsString("", mode: FileMode.write); + } +} diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 248a06de0..fe5e6efc4 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -61,6 +61,7 @@ dependencies: permission_handler: ^10.0.0 device_display_brightness: ^0.0.6 platform_device_id: ^1.0.1 + flutter_mailer: ^2.0.1 cake_backup: git: url: https://github.com/cake-tech/cake_backup.git From 51ea377a52febaeab9ea61b526e9623e772408c9 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Sun, 27 Nov 2022 14:44:35 +0200 Subject: [PATCH 05/13] Temporarily comment run app on error of run zone guard --- lib/main.dart | 58 +++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 4ffb168f6..da0b2c531 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -161,34 +161,38 @@ Future main() async { initialMigrationVersion: 17); runApp(App()); }, (error, stackTrace) async { + print("@@@@@@@@@@@@@@@@"); + print(error); + print(stackTrace); _saveException(error.toString(), stackTrace); - final sharedPreferences = await SharedPreferences.getInstance(); - final theme = ThemeList.deserialize( - raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? 0); - - final savedLanguageCode = - sharedPreferences.getString(PreferencesKey.currentLanguageCode) ?? - await LanguageService.localeDetection(); - runApp( - MaterialApp( - debugShowCheckedModeBanner: true, - theme: theme.themeData, - localizationsDelegates: [ - S.delegate, - GlobalCupertinoLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - ], - supportedLocales: S.delegate.supportedLocales, - locale: Locale(savedLanguageCode), - home: Scaffold( - body: FailurePage( - error: error.toString(), - stackTrace: stackTrace, - ), - ), - ), - ); + // TODO: this will trigger even there is no fatal error occurred so better not build a new app instance + // final sharedPreferences = await SharedPreferences.getInstance(); + // final theme = ThemeList.deserialize( + // raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? 0); + // + // final savedLanguageCode = + // sharedPreferences.getString(PreferencesKey.currentLanguageCode) ?? + // await LanguageService.localeDetection(); + // runApp( + // MaterialApp( + // debugShowCheckedModeBanner: true, + // theme: theme.themeData, + // localizationsDelegates: [ + // S.delegate, + // GlobalCupertinoLocalizations.delegate, + // GlobalMaterialLocalizations.delegate, + // GlobalWidgetsLocalizations.delegate, + // ], + // supportedLocales: S.delegate.supportedLocales, + // locale: Locale(savedLanguageCode), + // home: Scaffold( + // body: FailurePage( + // error: error.toString(), + // stackTrace: stackTrace, + // ), + // ), + // ), + // ); }); } From 03ea516e63384b9b5e4d28d4d483ddbf875dc36f Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 29 Nov 2022 14:03:14 +0200 Subject: [PATCH 06/13] Add initial alert for errors --- lib/main.dart | 76 +++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index da0b2c531..afa5804a0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,8 +9,10 @@ import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/src/screens/failure_page.dart'; +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/themes/theme_list.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -53,13 +55,19 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (errorDetails) { - print("@@@@@@@@@@@@@@@"); - print("FlutterError.onError"); - print(errorDetails); + print("@@@@@@@@@@@@@@@@@ in on error"); + print(errorDetails.exception.toString()); + _onError(errorDetails); _saveException(errorDetails.exception.toString(), errorDetails.stack); }; ErrorWidget.builder = (errorDetails) { + print("@@@@@@@@@@@@@@@@@ in widget error"); + // TODO: uncomment + // if (kDebugMode) { + // return ErrorWidget(errorDetails.exception); + // } + return FailurePage( error: errorDetails.exception.toString(), stackTrace: errorDetails.stack, @@ -161,38 +169,8 @@ Future main() async { initialMigrationVersion: 17); runApp(App()); }, (error, stackTrace) async { - print("@@@@@@@@@@@@@@@@"); - print(error); - print(stackTrace); - _saveException(error.toString(), stackTrace); - // TODO: this will trigger even there is no fatal error occurred so better not build a new app instance - // final sharedPreferences = await SharedPreferences.getInstance(); - // final theme = ThemeList.deserialize( - // raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? 0); - // - // final savedLanguageCode = - // sharedPreferences.getString(PreferencesKey.currentLanguageCode) ?? - // await LanguageService.localeDetection(); - // runApp( - // MaterialApp( - // debugShowCheckedModeBanner: true, - // theme: theme.themeData, - // localizationsDelegates: [ - // S.delegate, - // GlobalCupertinoLocalizations.delegate, - // GlobalMaterialLocalizations.delegate, - // GlobalWidgetsLocalizations.delegate, - // ], - // supportedLocales: S.delegate.supportedLocales, - // locale: Locale(savedLanguageCode), - // home: Scaffold( - // body: FailurePage( - // error: error.toString(), - // stackTrace: stackTrace, - // ), - // ), - // ), - // ); + print("@@@@@@@@@@@@@@@@ in run zone guard"); + _onError(FlutterErrorDetails(exception: error, stack: stackTrace)); }); } @@ -210,6 +188,34 @@ void _saveException(String? error, StackTrace? stackTrace) async { await file.writeAsString(jsonEncode(exception), mode: FileMode.append); } +void _onError(FlutterErrorDetails details) { + print("#############"); + print(details.exception.toString()); + WidgetsBinding.instance.addPostFrameCallback( + (timeStamp) { + showPopUp( + context: navigatorKey.currentContext!, + builder: (context) { + return AlertWithTwoActions( + isDividerExist: true, + alertTitle: S.of(context).error, + alertContent: "Oops, we got some error.\n\nPlease send crash report to our support team to make the application better.", + rightButtonText: S.of(context).send, + leftButtonText: "Don't send", + actionRightButton: () async { + Navigator.of(context).pop(); + }, + actionLeftButton: () { + Navigator.of(context).pop(); + _saveException(details.exception.toString(), details.stack); + }, + ); + }, + ); + }, + ); +} + Future initialSetup( {required SharedPreferences sharedPreferences, required Box nodes, From e904c0a7b751cee11031dd953ddf035df2d7f872 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Fri, 6 Jan 2023 19:42:37 +0200 Subject: [PATCH 07/13] Show popup on un-caught exceptions to send errors via email --- lib/main.dart | 65 ++++++++++++++--------- lib/src/screens/failure_page.dart | 87 ------------------------------- pubspec_base.yaml | 2 +- 3 files changed, 40 insertions(+), 114 deletions(-) delete mode 100644 lib/src/screens/failure_page.dart diff --git a/lib/main.dart b/lib/main.dart index d9f35805a..8e565e763 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,7 +9,6 @@ import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; -import 'package:cake_wallet/src/screens/failure_page.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/themes/theme_list.dart'; @@ -17,6 +16,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_mailer/flutter_mailer.dart'; import 'package:hive/hive.dart'; import 'package:cake_wallet/di.dart'; import 'package:path_provider/path_provider.dart'; @@ -57,31 +57,14 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (errorDetails) { - print("@@@@@@@@@@@@@@@@@ in on error"); - print(errorDetails.exception.toString()); _onError(errorDetails); - _saveException(errorDetails.exception.toString(), errorDetails.stack); - }; - - ErrorWidget.builder = (errorDetails) { - print("@@@@@@@@@@@@@@@@@ in widget error"); - // TODO: uncomment - // if (kDebugMode) { - // return ErrorWidget(errorDetails.exception); - // } - - return FailurePage( - error: errorDetails.exception.toString(), - stackTrace: errorDetails.stack, - ); }; /// A callback that is invoked when an unhandled error occurs in the root /// isolate. PlatformDispatcher.instance.onError = (error, stack) { - print("@@@@@@@@@@@@@@@"); - print("PlatformDispatcher.instance.onError"); - _saveException(error.toString(), stack); + _onError(FlutterErrorDetails(exception: error, stack: stack)); + return true; }; @@ -187,12 +170,42 @@ void _saveException(String? error, StackTrace? stackTrace) async { } }; - await file.writeAsString(jsonEncode(exception), mode: FileMode.append); + String separator = "\n\n==========================================================" + + "\n==========================================================\n\n"; + + await file.writeAsString( + jsonEncode(exception) + separator, + mode: FileMode.append, + ); } -void _onError(FlutterErrorDetails details) { - print("#############"); - print(details.exception.toString()); +void _sendExceptionFile() async { + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); + + print(file.readAsStringSync()); + + final MailOptions mailOptions = MailOptions( + subject: 'Mobile App Issue', + recipients: ['support@cakewallet.com'], + attachments: [file.path], + ); + + final result = await FlutterMailer.send(mailOptions); + + // clear file content if the error was sent or saved + // on android we can't know if it was sent or saved + if (result.name == MailerResponse.sent.name || + result.name == MailerResponse.saved.name || + result.name == MailerResponse.android.name) { + file.writeAsString("", mode: FileMode.write); + } +} + +void _onError(FlutterErrorDetails errorDetails) { + _saveException(errorDetails.exception.toString(), errorDetails.stack); + WidgetsBinding.instance.addPostFrameCallback( (timeStamp) { showPopUp( @@ -204,12 +217,12 @@ void _onError(FlutterErrorDetails details) { alertContent: "Oops, we got some error.\n\nPlease send crash report to our support team to make the application better.", rightButtonText: S.of(context).send, leftButtonText: "Don't send", - actionRightButton: () async { + actionRightButton: () { Navigator.of(context).pop(); + _sendExceptionFile(); }, actionLeftButton: () { Navigator.of(context).pop(); - _saveException(details.exception.toString(), details.stack); }, ); }, diff --git a/lib/src/screens/failure_page.dart b/lib/src/screens/failure_page.dart deleted file mode 100644 index ea3d75fcb..000000000 --- a/lib/src/screens/failure_page.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'dart:io'; - -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/widgets/primary_button.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_mailer/flutter_mailer.dart'; -import 'package:path_provider/path_provider.dart'; - -class FailurePage extends StatelessWidget { - final String? error; - final StackTrace? stackTrace; - - FailurePage({Key? key, this.error, this.stackTrace}); - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - return Scaffold( - backgroundColor: Colors.grey.shade400, - body: Center( - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: MediaQuery.of(context).size.width * 0.2), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Icon( - Icons.warning, - color: theme.errorColor, - size: 50, - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 20), - child: Text( - "Oops, we got some error.", - style: theme.textTheme.headline1?.copyWith(fontSize: 20), - ), - ), - Text( - "Please send crash report to our support team to make the application better.", - textAlign: TextAlign.center, - style: theme.textTheme.headline1?.copyWith(fontSize: 16), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 20), - child: PrimaryButton( - onPressed: _sendExceptionFile, - text: S.of(context).send, - textColor: Colors.white, - color: theme.accentTextTheme.bodyText1!.color!, - ), - ), - PrimaryButton( - onPressed: () { - }, - text: "Don't Send", - color: Theme.of(context).accentTextTheme.caption!.color!, - textColor: - Theme.of(context).primaryTextTheme.headline6!.color!, - ), - ], - ), - ), - ), - ); - } - - void _sendExceptionFile() async { - final appDocDir = await getApplicationDocumentsDirectory(); - - final file = File('${appDocDir.path}/error.txt'); - - print(file.readAsStringSync()); - - final MailOptions mailOptions = MailOptions( - subject: 'Mobile App Issue', - recipients: ['support@cakewallet.com'], - attachments: [file.path], - ); - - await FlutterMailer.send(mailOptions); - - // clear file content - // file.writeAsString("", mode: FileMode.write); - } -} diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 7981c6690..59ce2867d 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -61,7 +61,7 @@ dependencies: permission_handler: ^10.0.0 device_display_brightness: ^0.0.6 platform_device_id: ^1.0.1 - flutter_mailer: ^2.0.1 + flutter_mailer: ^2.0.2 cake_backup: git: url: https://github.com/cake-tech/cake_backup.git From a373253fd294320847bd3ef9805564ebd44e92bc Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 9 Jan 2023 18:16:50 +0200 Subject: [PATCH 08/13] Add localizations for error dialog content --- lib/main.dart | 9 ++++----- res/values/strings_de.arb | 4 +++- res/values/strings_en.arb | 4 +++- res/values/strings_es.arb | 4 +++- res/values/strings_fr.arb | 4 +++- res/values/strings_hi.arb | 4 +++- res/values/strings_hr.arb | 4 +++- res/values/strings_it.arb | 4 +++- res/values/strings_ja.arb | 4 +++- res/values/strings_ko.arb | 4 +++- res/values/strings_nl.arb | 4 +++- res/values/strings_pl.arb | 4 +++- res/values/strings_pt.arb | 4 +++- res/values/strings_ru.arb | 4 +++- res/values/strings_th.arb | 4 +++- res/values/strings_uk.arb | 4 +++- res/values/strings_zh.arb | 4 +++- 17 files changed, 52 insertions(+), 21 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8e565e763..a6594a097 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -154,7 +154,6 @@ Future main() async { initialMigrationVersion: 19); runApp(App()); }, (error, stackTrace) async { - print("@@@@@@@@@@@@@@@@ in run zone guard"); _onError(FlutterErrorDetails(exception: error, stack: stackTrace)); }); } @@ -165,8 +164,8 @@ void _saveException(String? error, StackTrace? stackTrace) async { final file = File('${appDocDir.path}/error.txt'); final exception = { "${DateTime.now()}": { - "error": error, - "stackTrace": stackTrace.toString(), + "Error": error, + "StackTrace": stackTrace.toString(), } }; @@ -214,9 +213,9 @@ void _onError(FlutterErrorDetails errorDetails) { return AlertWithTwoActions( isDividerExist: true, alertTitle: S.of(context).error, - alertContent: "Oops, we got some error.\n\nPlease send crash report to our support team to make the application better.", + alertContent: S.of(context).error_dialog_content, rightButtonText: S.of(context).send, - leftButtonText: "Don't send", + leftButtonText: S.of(context).do_not_send, actionRightButton: () { Navigator.of(context).pop(); _sendExceptionFile(); diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 9ba0a7553..65057fce2 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -679,5 +679,7 @@ "tor_only": "Nur Tor", "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein", "contact_list_contacts": "Kontakte", - "contact_list_wallets": "Meine Geldbörsen" + "contact_list_wallets": "Meine Geldbörsen", + "do_not_send": "Nicht senden", + "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie einen Absturzbericht an unser Support-Team, um die Anwendung zu verbessern." } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index e9a0c4d49..1be48ce47 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -679,5 +679,7 @@ "tor_only": "Tor only", "unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR", "contact_list_contacts": "Contacts", - "contact_list_wallets": "My Wallets" + "contact_list_wallets": "My Wallets", + "do_not_send": "Don't send", + "error_dialog_content": "Oops, we got some error.\n\nPlease send crash report to our support team to make the application better." } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 10c866676..a5ed4fe9e 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -679,5 +679,7 @@ "tor_only": "solo Tor", "unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado", "contact_list_contacts": "Contactos", - "contact_list_wallets": "Mis billeteras" + "contact_list_wallets": "Mis billeteras", + "do_not_send": "no enviar", + "error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe un informe de fallas a nuestro equipo de soporte para mejorar la aplicación." } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 99fbcd282..1d8eed7eb 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -677,5 +677,7 @@ "tor_only": "Tor uniquement", "unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné", "contact_list_contacts": "Contacts", - "contact_list_wallets": "Mes portefeuilles (wallets)" + "contact_list_wallets": "Mes portefeuilles (wallets)", + "do_not_send": "N'envoyez pas", + "error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer un rapport de plantage à notre équipe d'assistance pour améliorer l'application." } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index a5c27ddb4..df324f40b 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -679,5 +679,7 @@ "tor_only": "Tor केवल", "unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती" , "contact_list_contacts": "संपर्क", - "contact_list_wallets": "मेरा बटुआ" + "contact_list_wallets": "मेरा बटुआ", + "do_not_send": "मत भेजो", + "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया हमारी सहायता टीम को क्रैश रिपोर्ट भेजें।" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 9aa9f0b4f..97c39195c 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -679,5 +679,7 @@ "tor_only": "Samo Tor", "unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u", "contact_list_contacts": "Kontakti", - "contact_list_wallets": "Moji novčanici" + "contact_list_wallets": "Moji novčanici", + "do_not_send": "Ne šalji", + "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju." } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index e90fc20c2..59cbf5909 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -679,5 +679,7 @@ "tor_only": "Solo Tor", "unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato", "contact_list_contacts": "Contatti", - "contact_list_wallets": "I miei portafogli" + "contact_list_wallets": "I miei portafogli", + "do_not_send": "Non inviare", + "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare un rapporto sugli arresti anomali al nostro team di supporto per migliorare l'applicazione." } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 3c5a5d951..86d2bbaef 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -679,5 +679,7 @@ "tor_only": "Torのみ", "unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません", "contact_list_contacts": "連絡先", - "contact_list_wallets": "マイウォレット" + "contact_list_wallets": "マイウォレット", + "do_not_send": "送信しない", + "error_dialog_content": "エラーが発生しました。\n\nアプリケーションを改善するために、クラッシュ レポートをサポート チームに送信してください。" } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 216a3a143..847321465 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -679,5 +679,7 @@ "tor_only": "Tor 뿐", "unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.", "contact_list_contacts": "콘택트 렌즈", - "contact_list_wallets": "내 지갑" + "contact_list_wallets": "내 지갑", + "do_not_send": "보내지 마세요", + "error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오." } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 9ac0cd1d1..d3bca52b6 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -679,5 +679,7 @@ "tor_only": "Alleen Tor", "unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR", "contact_list_contacts": "Contacten", - "contact_list_wallets": "Mijn portefeuilles" + "contact_list_wallets": "Mijn portefeuilles", + "do_not_send": "Niet sturen", + "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur een crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren." } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 11bf637e5..4d93b8ee8 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -679,5 +679,7 @@ "tor_only": "Tylko Tor", "unmatched_currencies": "Waluta Twojego obecnego portfela nie odpowiada walucie zeskanowanego kodu QR", "contact_list_contacts": "Łączność", - "contact_list_wallets": "Moje portfele" + "contact_list_wallets": "Moje portfele", + "do_not_send": "Nie wysyłaj", + "error_dialog_content": "Ups, wystąpił błąd.\n\nPrześlij raport o awarii do naszego zespołu wsparcia, aby ulepszyć aplikację." } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8529aadb8..acdb861af 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -678,5 +678,7 @@ "tor_only": "Tor apenas", "unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado", "contact_list_contacts": "Contatos", - "contact_list_wallets": "minhas carteiras" + "contact_list_wallets": "minhas carteiras", + "do_not_send": "não envie", + "error_dialog_content": "Ops, houve algum erro.\n\nEnvie um relatório de falha para nossa equipe de suporte para melhorar o aplicativo." } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 1ba5fd85c..dadcc67e4 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -679,5 +679,7 @@ "tor_only": "Только Tor", "unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.", "contact_list_contacts": "Контакты", - "contact_list_wallets": "Мои кошельки" + "contact_list_wallets": "Мои кошельки", + "do_not_send": "Не отправлять", + "error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше." } diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 242a8d110..60a09b747 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -677,5 +677,7 @@ "tor_only" : "Tor เท่านั้น", "unmatched_currencies" : "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน", "contact_list_contacts": "ติดต่อ", - "contact_list_wallets": "กระเป๋าเงินของฉัน" + "contact_list_wallets": "กระเป๋าเงินของฉัน", + "do_not_send": "อย่าส่ง", + "error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น" } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 4fad9a19d..284b59c29 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -678,5 +678,7 @@ "tor_only": "Тільки Tor", "unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду", "contact_list_contacts": "Контакти", - "contact_list_wallets": "Мої гаманці" + "contact_list_wallets": "Мої гаманці", + "do_not_send": "Не надсилайте", + "error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток." } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 7c0f4ab74..d04831cc2 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -677,5 +677,7 @@ "tor_only": "仅限 Tor", "unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配", "contact_list_contacts": "联系人", - "contact_list_wallets": "我的钱包" + "contact_list_wallets": "我的钱包", + "do_not_send": "不要发送", + "error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队,以改进应用程序。" } From 8d68ccfc7b0a3a7491d3665da798c9b41c21e4a9 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 9 Jan 2023 20:03:26 +0200 Subject: [PATCH 09/13] Ignore UI issues from exceptions report --- lib/main.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index a6594a097..126bd213f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -57,7 +57,10 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (errorDetails) { - _onError(errorDetails); + // if not a UI error + if (errorDetails.library != "widgets library") { + _onError(errorDetails); + } }; /// A callback that is invoked when an unhandled error occurs in the root @@ -193,8 +196,8 @@ void _sendExceptionFile() async { final result = await FlutterMailer.send(mailOptions); - // clear file content if the error was sent or saved - // on android we can't know if it was sent or saved + // Clear file content if the error was sent or saved. + // On android we can't know if it was sent or saved if (result.name == MailerResponse.sent.name || result.name == MailerResponse.saved.name || result.name == MailerResponse.android.name) { From e4af355b2493dc3aaba6246f7bad54d58cbab877 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 9 Jan 2023 20:31:24 +0200 Subject: [PATCH 10/13] Fix Translation typo [skip ci] --- README.md | 1 + res/values/strings_de.arb | 2 +- res/values/strings_en.arb | 2 +- res/values/strings_es.arb | 2 +- res/values/strings_fr.arb | 2 +- res/values/strings_hi.arb | 2 +- res/values/strings_it.arb | 2 +- res/values/strings_ja.arb | 2 +- res/values/strings_nl.arb | 2 +- res/values/strings_pt.arb | 2 +- 10 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f485ca244..e4d057e94 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull reque - Japanese - Chinese - Korean +- Thai ## Add a new language diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 65057fce2..a8a4f8086 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "Kontakte", "contact_list_wallets": "Meine Geldbörsen", "do_not_send": "Nicht senden", - "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie einen Absturzbericht an unser Support-Team, um die Anwendung zu verbessern." + "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern." } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 1be48ce47..07937b0e7 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "Contacts", "contact_list_wallets": "My Wallets", "do_not_send": "Don't send", - "error_dialog_content": "Oops, we got some error.\n\nPlease send crash report to our support team to make the application better." + "error_dialog_content": "Oops, we got some error.\n\nPlease send the crash report to our support team to make the application better." } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index a5ed4fe9e..b69978d6f 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "Contactos", "contact_list_wallets": "Mis billeteras", "do_not_send": "no enviar", - "error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe un informe de fallas a nuestro equipo de soporte para mejorar la aplicación." + "error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe el informe de bloqueo a nuestro equipo de soporte para mejorar la aplicación." } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 1d8eed7eb..df8f1e48d 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -679,5 +679,5 @@ "contact_list_contacts": "Contacts", "contact_list_wallets": "Mes portefeuilles (wallets)", "do_not_send": "N'envoyez pas", - "error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer un rapport de plantage à notre équipe d'assistance pour améliorer l'application." + "error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer le rapport de plantage à notre équipe d'assistance pour améliorer l'application." } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index df324f40b..40df82dc0 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "संपर्क", "contact_list_wallets": "मेरा बटुआ", "do_not_send": "मत भेजो", - "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया हमारी सहायता टीम को क्रैश रिपोर्ट भेजें।" + "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।" } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 59cbf5909..d48a96baa 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "Contatti", "contact_list_wallets": "I miei portafogli", "do_not_send": "Non inviare", - "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare un rapporto sugli arresti anomali al nostro team di supporto per migliorare l'applicazione." + "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju." } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 86d2bbaef..d928b960e 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "連絡先", "contact_list_wallets": "マイウォレット", "do_not_send": "送信しない", - "error_dialog_content": "エラーが発生しました。\n\nアプリケーションを改善するために、クラッシュ レポートをサポート チームに送信してください。" + "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare il rapporto sull'arresto anomalo al nostro team di supporto per migliorare l'applicazione." } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index d3bca52b6..eabb30216 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -681,5 +681,5 @@ "contact_list_contacts": "Contacten", "contact_list_wallets": "Mijn portefeuilles", "do_not_send": "Niet sturen", - "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur een crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren." + "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren." } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index acdb861af..cd7a79b0e 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -680,5 +680,5 @@ "contact_list_contacts": "Contatos", "contact_list_wallets": "minhas carteiras", "do_not_send": "não envie", - "error_dialog_content": "Ops, houve algum erro.\n\nEnvie um relatório de falha para nossa equipe de suporte para melhorar o aplicativo." + "error_dialog_content": "Ops, houve algum erro.\n\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo." } From d79b481d3e883a0718e5ec5c188f9d40c993c785 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Thu, 12 Jan 2023 17:08:38 +0200 Subject: [PATCH 11/13] Wrap sending error file in try/catch for unexpected behaviors [skip ci] --- lib/main.dart | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 126bd213f..78879bdb5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -172,8 +172,9 @@ void _saveException(String? error, StackTrace? stackTrace) async { } }; - String separator = "\n\n==========================================================" + - "\n==========================================================\n\n"; + const String separator = + '''\n\n========================================================== + ==========================================================\n\n'''; await file.writeAsString( jsonEncode(exception) + separator, @@ -182,26 +183,28 @@ void _saveException(String? error, StackTrace? stackTrace) async { } void _sendExceptionFile() async { - final appDocDir = await getApplicationDocumentsDirectory(); + try { + final appDocDir = await getApplicationDocumentsDirectory(); - final file = File('${appDocDir.path}/error.txt'); + final file = File('${appDocDir.path}/error.txt'); - print(file.readAsStringSync()); + final MailOptions mailOptions = MailOptions( + subject: 'Mobile App Issue', + recipients: ['support@cakewallet.com'], + attachments: [file.path], + ); - final MailOptions mailOptions = MailOptions( - subject: 'Mobile App Issue', - recipients: ['support@cakewallet.com'], - attachments: [file.path], - ); + final result = await FlutterMailer.send(mailOptions); - final result = await FlutterMailer.send(mailOptions); - - // Clear file content if the error was sent or saved. - // On android we can't know if it was sent or saved - if (result.name == MailerResponse.sent.name || - result.name == MailerResponse.saved.name || - result.name == MailerResponse.android.name) { - file.writeAsString("", mode: FileMode.write); + // Clear file content if the error was sent or saved. + // On android we can't know if it was sent or saved + if (result.name == MailerResponse.sent.name || + result.name == MailerResponse.saved.name || + result.name == MailerResponse.android.name) { + file.writeAsString("", mode: FileMode.write); + } + } catch (e, s) { + _saveException(e.toString(), s); } } From c1c49e878eb8d825c6630b9934095dae91f5010f Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 24 Jan 2023 02:46:22 +0200 Subject: [PATCH 12/13] [skip ci] - Revert disabling UI error reporting as it will also disable some errors from the view models - Fix warnings in node list row (potential nullability issue fix) --- lib/main.dart | 5 +---- lib/src/screens/nodes/widgets/node_list_row.dart | 8 ++------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 78879bdb5..a8d0064f4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -57,10 +57,7 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = (errorDetails) { - // if not a UI error - if (errorDetails.library != "widgets library") { - _onError(errorDetails); - } + _onError(errorDetails); }; /// A callback that is invoked when an unhandled error occurs in the root diff --git a/lib/src/screens/nodes/widgets/node_list_row.dart b/lib/src/screens/nodes/widgets/node_list_row.dart index 580aba170..90bb3eba1 100644 --- a/lib/src/screens/nodes/widgets/node_list_row.dart +++ b/lib/src/screens/nodes/widgets/node_list_row.dart @@ -1,9 +1,5 @@ -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/src/screens/nodes/widgets/node_indicator.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class NodeListRow extends StandardListRow { @@ -23,7 +19,7 @@ class NodeListRow extends StandardListRow { builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.done: - return NodeIndicator(isLive: (snapshot.data as bool)??false); + return NodeIndicator(isLive: (snapshot.data as bool?) ?? false); default: return NodeIndicator(isLive: false); } @@ -40,7 +36,7 @@ class NodeHeaderListRow extends StandardListRow { return SizedBox( width: 20, child: Icon(Icons.add, - color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0), + color: Theme.of(context).accentTextTheme.subtitle1?.color, size: 24.0), ); } } From 33337f42d06acf636910b70ac9cb9f2011aa1c50 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 24 Jan 2023 03:06:40 +0200 Subject: [PATCH 13/13] [skip ci] merge master --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f0653f93..96f59e704 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,8 @@ Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull reque - Korean - Thai - Arabic -- Burmese - Turkish +- Burmese ## Add a new language