Show popup on un-caught exceptions to send errors via email

This commit is contained in:
OmarHatem 2023-01-06 19:42:37 +02:00
parent baeff1ea14
commit e904c0a7b7
3 changed files with 40 additions and 114 deletions

View file

@ -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<void> 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<void>(
@ -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);
},
);
},

View file

@ -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);
}
}

View file

@ -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