Merge pull request #720 from cake-tech/CW-237-enhance-error-catching-reporting

Cw 237 enhance error catching reporting
This commit is contained in:
Omar Hatem 2023-01-25 15:30:15 +02:00 committed by GitHub
commit 4d3b891e79
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 152 additions and 35 deletions

View file

@ -100,9 +100,10 @@ Edit the applicable `strings_XX.arb` file in `res/values/` and open a pull reque
- Japanese - Japanese
- Chinese - Chinese
- Korean - Korean
- Thai
- Arabic - Arabic
- Burmese
- Turkish - Turkish
- Burmese
## Add a new language ## Add a new language

View file

@ -1,14 +1,22 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/buy/order.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_category.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/ionia/ionia_merchant.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/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/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_mailer/flutter_mailer.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -44,9 +52,22 @@ final rootKey = GlobalKey<RootState>();
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>(); final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
Future<void> main() async { Future<void> main() async {
try {
await runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (errorDetails) {
_onError(errorDetails);
};
/// A callback that is invoked when an unhandled error occurs in the root
/// isolate.
PlatformDispatcher.instance.onError = (error, stack) {
_onError(FlutterErrorDetails(exception: error, stack: stack));
return true;
};
final appDir = await getApplicationDocumentsDirectory(); final appDir = await getApplicationDocumentsDirectory();
await Hive.close(); await Hive.close();
Hive.init(appDir.path); Hive.init(appDir.path);
@ -132,18 +153,84 @@ Future<void> main() async {
secureStorage: secureStorage, secureStorage: secureStorage,
initialMigrationVersion: 19); initialMigrationVersion: 19);
runApp(App()); runApp(App());
} catch (e, stacktrace) { }, (error, stackTrace) async {
runApp(MaterialApp( _onError(FlutterErrorDetails(exception: error, stack: stackTrace));
debugShowCheckedModeBanner: true, });
home: Scaffold(
body: Container(
margin:
EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
child: Text(
'Error:\n${e.toString()}\nStacktrace: $stacktrace',
style: TextStyle(fontSize: 22),
)))));
} }
void _saveException(String? error, StackTrace? stackTrace) async {
final appDocDir = await getApplicationDocumentsDirectory();
final file = File('${appDocDir.path}/error.txt');
final exception = {
"${DateTime.now()}": {
"Error": error,
"StackTrace": stackTrace.toString(),
}
};
const String separator =
'''\n\n==========================================================
==========================================================\n\n''';
await file.writeAsString(
jsonEncode(exception) + separator,
mode: FileMode.append,
);
}
void _sendExceptionFile() async {
try {
final appDocDir = await getApplicationDocumentsDirectory();
final file = File('${appDocDir.path}/error.txt');
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);
}
} catch (e, s) {
_saveException(e.toString(), s);
}
}
void _onError(FlutterErrorDetails errorDetails) {
_saveException(errorDetails.exception.toString(), errorDetails.stack);
WidgetsBinding.instance.addPostFrameCallback(
(timeStamp) {
showPopUp<void>(
context: navigatorKey.currentContext!,
builder: (context) {
return AlertWithTwoActions(
isDividerExist: true,
alertTitle: S.of(context).error,
alertContent: S.of(context).error_dialog_content,
rightButtonText: S.of(context).send,
leftButtonText: S.of(context).do_not_send,
actionRightButton: () {
Navigator.of(context).pop();
_sendExceptionFile();
},
actionLeftButton: () {
Navigator.of(context).pop();
},
);
},
);
},
);
} }
Future<void> initialSetup( Future<void> initialSetup(

View file

@ -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/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:cake_wallet/src/widgets/standard_list.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class NodeListRow extends StandardListRow { class NodeListRow extends StandardListRow {
@ -23,7 +19,7 @@ class NodeListRow extends StandardListRow {
builder: (context, snapshot) { builder: (context, snapshot) {
switch (snapshot.connectionState) { switch (snapshot.connectionState) {
case ConnectionState.done: case ConnectionState.done:
return NodeIndicator(isLive: (snapshot.data as bool)??false); return NodeIndicator(isLive: (snapshot.data as bool?) ?? false);
default: default:
return NodeIndicator(isLive: false); return NodeIndicator(isLive: false);
} }
@ -40,7 +36,7 @@ class NodeHeaderListRow extends StandardListRow {
return SizedBox( return SizedBox(
width: 20, width: 20,
child: Icon(Icons.add, child: Icon(Icons.add,
color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0), color: Theme.of(context).accentTextTheme.subtitle1?.color, size: 24.0),
); );
} }
} }

View file

@ -61,6 +61,7 @@ dependencies:
permission_handler: ^10.0.0 permission_handler: ^10.0.0
device_display_brightness: ^0.0.6 device_display_brightness: ^0.0.6
platform_device_id: ^1.0.1 platform_device_id: ^1.0.1
flutter_mailer: ^2.0.2
cake_backup: cake_backup:
git: git:
url: https://github.com/cake-tech/cake_backup.git url: https://github.com/cake-tech/cake_backup.git

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein", "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein",
"orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.", "orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.",
"contact_list_contacts": "Kontakte", "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 den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR", "unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR",
"orbot_running_alert": "Please make sure Orbot is running prior to connecting to this node.", "orbot_running_alert": "Please make sure Orbot is running prior to connecting to this node.",
"contact_list_contacts": "Contacts", "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 the crash report to our support team to make the application better."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado", "unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado",
"orbot_running_alert": "Asegúrese de que Orbot se esté ejecutando antes de conectarse a este nodo.", "orbot_running_alert": "Asegúrese de que Orbot se esté ejecutando antes de conectarse a este nodo.",
"contact_list_contacts": "Contactos", "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 el informe de bloqueo a nuestro equipo de soporte para mejorar la aplicación."
} }

View file

@ -678,5 +678,7 @@
"orbot_running_alert": "Veuillez vous assurer qu'Orbot est en cours d'exécution avant de vous connecter à ce nœud.", "orbot_running_alert": "Veuillez vous assurer qu'Orbot est en cours d'exécution avant de vous connecter à ce nœud.",
"unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné", "unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné",
"contact_list_contacts": "Contacts", "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 le rapport de plantage à notre équipe d'assistance pour améliorer l'application."
} }

View file

@ -680,5 +680,7 @@
"orbot_running_alert": "कृपया सुनिश्चित करें कि इस नोड से कनेक्ट करने से पहले Orbot चल रहा है।", "orbot_running_alert": "कृपया सुनिश्चित करें कि इस नोड से कनेक्ट करने से पहले Orbot चल रहा है।",
"unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती" , "unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती" ,
"contact_list_contacts": "संपर्क", "contact_list_contacts": "संपर्क",
"contact_list_wallets": "मेरा बटुआ" "contact_list_wallets": "मेरा बटुआ",
"do_not_send": "मत भेजो",
"error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।"
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u", "unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u",
"orbot_running_alert": "Provjerite radi li Orbot prije spajanja na ovaj čvor.", "orbot_running_alert": "Provjerite radi li Orbot prije spajanja na ovaj čvor.",
"contact_list_contacts": "Kontakti", "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."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato", "unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato",
"orbot_running_alert": "Assicurati che Orbot sia in esecuzione prima di connetterti a questo nodo.", "orbot_running_alert": "Assicurati che Orbot sia in esecuzione prima di connetterti a questo nodo.",
"contact_list_contacts": "Contatti", "contact_list_contacts": "Contatti",
"contact_list_wallets": "I miei portafogli" "contact_list_wallets": "I miei portafogli",
"do_not_send": "Non inviare",
"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."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません", "unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません",
"orbot_running_alert": "このードに接続する前に、Orbot が実行されていることを確認してください", "orbot_running_alert": "このードに接続する前に、Orbot が実行されていることを確認してください",
"contact_list_contacts": "連絡先", "contact_list_contacts": "連絡先",
"contact_list_wallets": "マイウォレット" "contact_list_wallets": "マイウォレット",
"do_not_send": "送信しない",
"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."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.", "unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.",
"orbot_running_alert": "이 노드에 연결하기 전에 Orbot이 실행 중인지 확인하십시오.", "orbot_running_alert": "이 노드에 연결하기 전에 Orbot이 실행 중인지 확인하십시오.",
"contact_list_contacts": "콘택트 렌즈", "contact_list_contacts": "콘택트 렌즈",
"contact_list_wallets": "내 지갑" "contact_list_wallets": "내 지갑",
"do_not_send": "보내지 마세요",
"error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR", "unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR",
"orbot_running_alert": "Zorg ervoor dat Orbot actief is voordat u verbinding maakt met dit knooppunt.", "orbot_running_alert": "Zorg ervoor dat Orbot actief is voordat u verbinding maakt met dit knooppunt.",
"contact_list_contacts": "Contacten", "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 het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren."
} }

View file

@ -680,5 +680,7 @@
"tor_only": "Tylko sieć Tor", "tor_only": "Tylko sieć Tor",
"unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR", "unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR",
"contact_list_contacts": "Łączność", "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ę."
} }

View file

@ -679,5 +679,7 @@
"unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado", "unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado",
"orbot_running_alert": "Certifique-se de que o Orbot esteja em execução antes de se conectar a este nó.", "orbot_running_alert": "Certifique-se de que o Orbot esteja em execução antes de se conectar a este nó.",
"contact_list_contacts": "Contatos", "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\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo."
} }

View file

@ -680,5 +680,7 @@
"unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.", "unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.",
"orbot_running_alert": "Перед подключением к этому узлу убедитесь, что Orbot запущен.", "orbot_running_alert": "Перед подключением к этому узлу убедитесь, что Orbot запущен.",
"contact_list_contacts": "Контакты", "contact_list_contacts": "Контакты",
"contact_list_wallets": "Мои кошельки" "contact_list_wallets": "Мои кошельки",
"do_not_send": "Не отправлять",
"error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше."
} }

View file

@ -678,5 +678,7 @@
"unmatched_currencies" : "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน", "unmatched_currencies" : "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน",
"orbot_running_alert": "โปรดตรวจสอบว่า Orbot กำลังทำงานก่อนที่จะเชื่อมต่อกับโหนดนี้", "orbot_running_alert": "โปรดตรวจสอบว่า Orbot กำลังทำงานก่อนที่จะเชื่อมต่อกับโหนดนี้",
"contact_list_contacts": "ติดต่อ", "contact_list_contacts": "ติดต่อ",
"contact_list_wallets": "กระเป๋าเงินของฉัน" "contact_list_wallets": "กระเป๋าเงินของฉัน",
"do_not_send": "อย่าส่ง",
"error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น"
} }

View file

@ -679,5 +679,7 @@
"unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду", "unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду",
"orbot_running_alert": "Перед підключенням до цього вузла переконайтеся, що Orbot запущено.", "orbot_running_alert": "Перед підключенням до цього вузла переконайтеся, що Orbot запущено.",
"contact_list_contacts": "Контакти", "contact_list_contacts": "Контакти",
"contact_list_wallets": "Мої гаманці" "contact_list_wallets": "Мої гаманці",
"do_not_send": "Не надсилайте",
"error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток."
} }

View file

@ -678,5 +678,7 @@
"unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配", "unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配",
"orbot_running_alert": "请确保 Orbot 在连接到此节点之前正在运行。", "orbot_running_alert": "请确保 Orbot 在连接到此节点之前正在运行。",
"contact_list_contacts": "联系人", "contact_list_contacts": "联系人",
"contact_list_wallets": "我的钱包" "contact_list_wallets": "我的钱包",
"do_not_send": "不要发送",
"error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队以改进应用程序。"
} }