mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Don't dump all the debug info to the error reporting
This commit is contained in:
@@ -101,7 +101,8 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
|
|
||||||
if (error is TimeoutException) {
|
if (error is TimeoutException) {
|
||||||
issueTitle = 'Network Timeout';
|
issueTitle = 'Network Timeout';
|
||||||
issueErrorMessage = 'The connection to the server timed out. Please check your '
|
issueErrorMessage =
|
||||||
|
'The connection to the server timed out. Please check your '
|
||||||
'internet connection and try again.';
|
'internet connection and try again.';
|
||||||
} else if (error is FlutterErrorDetails) {
|
} else if (error is FlutterErrorDetails) {
|
||||||
issueTitle = 'Application Error';
|
issueTitle = 'Application Error';
|
||||||
@@ -116,7 +117,7 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String fullStackTrace = stackTrace?.toString() ?? 'No stack trace available.';
|
final String fullStackTrace = stackTrace?.toString() ?? 'No stack trace available.';
|
||||||
final applicationLogs = InMemoryLogStore().formattedLogs;
|
final applicationLogs = InMemoryLogStore().getFormattedLogs();
|
||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
context: dialogContext,
|
context: dialogContext,
|
||||||
@@ -127,15 +128,9 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
spacing: 8,
|
spacing: 8,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(icon, color: Theme.of(context).colorScheme.error),
|
||||||
icon,
|
|
||||||
color: Theme.of(context).colorScheme.error,
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(errorTitle, style: TextStyle(color: Theme.of(context).colorScheme.error)),
|
||||||
errorTitle,
|
|
||||||
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -150,10 +145,7 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
tilePadding: EdgeInsets.zero,
|
tilePadding: EdgeInsets.zero,
|
||||||
title: Text(i18n.errorViewDetails),
|
title: Text(i18n.errorViewDetails),
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(issueErrorMessage, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
issueErrorMessage,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
@@ -166,15 +158,13 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
CopyToClipboardButton(
|
CopyToClipboardButton(
|
||||||
text: 'Error Title: $issueTitle\n'
|
text:
|
||||||
|
'Error Title: $issueTitle\n'
|
||||||
'Error Message: $issueErrorMessage\n\n'
|
'Error Message: $issueErrorMessage\n\n'
|
||||||
'Stack Trace:\n$fullStackTrace',
|
'Stack Trace:\n$fullStackTrace',
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(i18n.applicationLogs, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||||
i18n.applicationLogs,
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
@@ -182,10 +172,12 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
...applicationLogs.map((entry) => Text(
|
...applicationLogs.map(
|
||||||
entry,
|
(entry) => Text(
|
||||||
style: TextStyle(fontSize: 12.0, color: Colors.grey[700]),
|
entry,
|
||||||
))
|
style: TextStyle(fontSize: 12.0, color: Colors.grey[700]),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -215,7 +207,8 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
'App logs (last ${applicationLogs.length} entries):\n'
|
'App logs (last ${applicationLogs.length} entries):\n'
|
||||||
'```\n$logText\n```',
|
'```\n$logText\n```',
|
||||||
);
|
);
|
||||||
final githubIssueUrl = '$GITHUB_ISSUES_BUG_URL'
|
final githubIssueUrl =
|
||||||
|
'$GITHUB_ISSUES_BUG_URL'
|
||||||
'&title=$issueTitle'
|
'&title=$issueTitle'
|
||||||
'&description=$description';
|
'&description=$description';
|
||||||
final Uri reportUri = Uri.parse(githubIssueUrl);
|
final Uri reportUri = Uri.parse(githubIssueUrl);
|
||||||
@@ -226,9 +219,9 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
|
|||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
logger.warning('Error launching URL: $e');
|
logger.warning('Error launching URL: $e');
|
||||||
}
|
}
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(
|
||||||
SnackBar(content: Text('Error opening issue tracker: $e')),
|
context,
|
||||||
);
|
).showSnackBar(SnackBar(content: Text('Error opening issue tracker: $e')));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -248,10 +241,7 @@ class CopyToClipboardButton extends StatelessWidget {
|
|||||||
final logger = Logger('CopyToClipboardButton');
|
final logger = Logger('CopyToClipboardButton');
|
||||||
final String text;
|
final String text;
|
||||||
|
|
||||||
CopyToClipboardButton({
|
CopyToClipboardButton({required this.text, super.key});
|
||||||
required this.text,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -265,21 +255,23 @@ class CopyToClipboardButton extends StatelessWidget {
|
|||||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Clipboard.setData(ClipboardData(text: text)).then((_) {
|
Clipboard.setData(ClipboardData(text: text))
|
||||||
if (context.mounted) {
|
.then((_) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
if (context.mounted) {
|
||||||
const SnackBar(content: Text('Details copied to clipboard!')),
|
ScaffoldMessenger.of(
|
||||||
);
|
context,
|
||||||
}
|
).showSnackBar(const SnackBar(content: Text('Details copied to clipboard!')));
|
||||||
}).catchError((copyError) {
|
}
|
||||||
logger.warning('Error copying to clipboard: $copyError');
|
})
|
||||||
|
.catchError((copyError) {
|
||||||
|
logger.warning('Error copying to clipboard: $copyError');
|
||||||
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(
|
||||||
const SnackBar(content: Text('Could not copy details.')),
|
context,
|
||||||
);
|
).showSnackBar(const SnackBar(content: Text('Could not copy details.')));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -290,9 +282,7 @@ void showDeleteDialog(BuildContext context, String confirmDeleteName, Log log) a
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext contextDialog) {
|
builder: (BuildContext contextDialog) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
content: Text(
|
content: Text(AppLocalizations.of(context).confirmDelete(confirmDeleteName)),
|
||||||
AppLocalizations.of(context).confirmDelete(confirmDeleteName),
|
|
||||||
),
|
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
key: const ValueKey('cancel-button'),
|
key: const ValueKey('cancel-button'),
|
||||||
@@ -387,7 +377,10 @@ List<Widget> formatApiErrors(List<ApiError> errors, {Color? color}) {
|
|||||||
|
|
||||||
for (final error in errors) {
|
for (final error in errors) {
|
||||||
errorList.add(
|
errorList.add(
|
||||||
Text(error.key, style: TextStyle(fontWeight: FontWeight.bold, color: textColor)),
|
Text(
|
||||||
|
error.key,
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold, color: textColor),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
print(error.errorMessages);
|
print(error.errorMessages);
|
||||||
@@ -408,7 +401,10 @@ List<Widget> formatTextErrors(List<String> errors, {String? title, Color? color}
|
|||||||
|
|
||||||
if (title != null) {
|
if (title != null) {
|
||||||
errorList.add(
|
errorList.add(
|
||||||
Text(title, style: TextStyle(fontWeight: FontWeight.bold, color: textColor)),
|
Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold, color: textColor),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,11 +454,7 @@ class GeneralErrorsWidget extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.error_outline, color: Theme.of(context).colorScheme.error),
|
Icon(Icons.error_outline, color: Theme.of(context).colorScheme.error),
|
||||||
...formatTextErrors(
|
...formatTextErrors(widgets, title: title, color: Theme.of(context).colorScheme.error),
|
||||||
widgets,
|
|
||||||
title: title,
|
|
||||||
color: Theme.of(context).colorScheme.error,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -41,10 +41,16 @@ class InMemoryLogStore {
|
|||||||
|
|
||||||
List<LogRecord> get logs => List.unmodifiable(_logs);
|
List<LogRecord> get logs => List.unmodifiable(_logs);
|
||||||
|
|
||||||
List<String> get formattedLogs => _logs
|
List<String> getFormattedLogs({Level? minLevel}) {
|
||||||
.map((log) =>
|
final level = minLevel ?? Logger.root.level;
|
||||||
'${log.time.toIso8601String()} ${log.level.name} [${log.loggerName}] ${log.message}')
|
return _logs
|
||||||
.toList();
|
.where((log) => log.level >= level)
|
||||||
|
.map(
|
||||||
|
(log) =>
|
||||||
|
'${log.time.toIso8601String()} ${log.level.name} [${log.loggerName}] ${log.message}',
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
void clear() => _logs.clear();
|
void clear() => _logs.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,12 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('correctly adds LogRecords', () {
|
test('correctly adds LogRecords', () {
|
||||||
|
logStore.add(LogRecord(Level.FINE, 'this is fine!!!', 'testLogger'));
|
||||||
logStore.add(LogRecord(Level.INFO, 'this is a test', 'testLogger'));
|
logStore.add(LogRecord(Level.INFO, 'this is a test', 'testLogger'));
|
||||||
|
|
||||||
expect(logStore.logs.length, 1);
|
expect(logStore.logs.length, 2);
|
||||||
expect(logStore.formattedLogs.length, 1);
|
expect(logStore.getFormattedLogs(minLevel: Level.INFO).length, 1);
|
||||||
|
expect(logStore.getFormattedLogs(minLevel: Level.FINE).length, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('total number of logs is limited', () {
|
test('total number of logs is limited', () {
|
||||||
|
|||||||
Reference in New Issue
Block a user