Refactor the general error popup

This should make it clearer where the messages and titles come from
This commit is contained in:
Roland Geider
2025-09-04 14:34:52 +02:00
parent 22924d1cf3
commit 0f44e0b25f
2 changed files with 46 additions and 47 deletions

View File

@@ -87,37 +87,35 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
return;
}
final i18n = AppLocalizations.of(dialogContext);
// If possible, determine the error title and message based on the error type.
bool isNetworkError = false;
String errorTitle = 'An error occurred';
String errorMessage = error.toString();
// (Note that issue titles and error messages are not localized)
bool allowReportIssue = true;
String issueTitle = 'An error occurred';
String issueErrorMessage = error.toString();
String errorTitle = i18n.anErrorOccurred;
String errorDescription = i18n.errorInfoDescription;
var icon = Icons.error;
if (error is TimeoutException) {
errorTitle = 'Network Timeout';
errorMessage =
'The connection to the server timed out. Please check your internet connection and try again.';
issueTitle = 'Network Timeout';
issueErrorMessage = 'The connection to the server timed out. Please check your '
'internet connection and try again.';
} else if (error is FlutterErrorDetails) {
errorTitle = 'Application Error';
errorMessage = error.exceptionAsString();
issueTitle = 'Application Error';
issueErrorMessage = error.exceptionAsString();
} else if (error is MissingRequiredKeysException) {
errorTitle = 'Missing Required Key';
issueTitle = 'Missing Required Key';
} else if (error is SocketException) {
isNetworkError = true;
allowReportIssue = false;
icon = Icons.signal_wifi_connected_no_internet_4_outlined;
errorTitle = i18n.errorCouldNotConnectToServer;
errorDescription = i18n.errorCouldNotConnectToServerDetails;
}
/*
else if (error is PlatformException) {
errorTitle = 'Problem with media';
errorMessage =
'There was a problem loading the media. This can be a e.g. problem with the codec that'
'is not supported by your device. Original error message: ${error.message}';
}
*/
final String fullStackTrace = stackTrace?.toString() ?? 'No stack trace available.';
final i18n = AppLocalizations.of(dialogContext);
showDialog(
context: dialogContext,
barrierDismissible: false,
@@ -128,12 +126,12 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
isNetworkError ? Icons.signal_wifi_connected_no_internet_4_outlined : Icons.error,
icon,
color: Theme.of(context).colorScheme.error,
),
Expanded(
child: Text(
isNetworkError ? i18n.errorCouldNotConnectToServer : i18n.anErrorOccurred,
errorTitle,
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
),
@@ -142,11 +140,7 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
content: SingleChildScrollView(
child: ListBody(
children: [
Text(
isNetworkError
? i18n.errorCouldNotConnectToServerDetails
: i18n.errorInfoDescription,
),
Text(errorDescription),
const SizedBox(height: 8),
Text(i18n.errorInfoDescription2),
const SizedBox(height: 10),
@@ -155,7 +149,7 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
title: Text(i18n.errorViewDetails),
children: [
Text(
errorMessage,
issueErrorMessage,
style: const TextStyle(fontWeight: FontWeight.bold),
),
Container(
@@ -178,14 +172,17 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
onPressed: () {
final String clipboardText =
'Error Title: $errorTitle\nError Message: $errorMessage\n\nStack Trace:\n$fullStackTrace';
final String clipboardText = 'Error Title: $issueTitle\n'
'Error Message: $issueErrorMessage\n\n'
'Stack Trace:\n$fullStackTrace';
Clipboard.setData(ClipboardData(text: clipboardText)).then((_) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Error details copied to clipboard!')),
);
}).catchError((copyError) {
if (kDebugMode) logger.fine('Error copying to clipboard: $copyError');
if (kDebugMode) {
logger.fine('Error copying to clipboard: $copyError');
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Could not copy details.')),
);
@@ -198,7 +195,7 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
),
),
actions: [
if (!isNetworkError)
if (allowReportIssue)
TextButton(
child: const Text('Report issue'),
onPressed: () async {
@@ -206,20 +203,22 @@ void showGeneralErrorDialog(dynamic error, StackTrace? stackTrace, {BuildContext
'## Description\n\n'
'[Please describe what you were doing when the error occurred.]\n\n'
'## Error details\n\n'
'Error title: $errorTitle\n'
'Error message: $errorMessage\n'
'Error title: $issueTitle\n'
'Error message: $issueErrorMessage\n'
'Stack trace:\n'
'```\n$stackTrace\n```',
);
final githubIssueUrl = '$GITHUB_ISSUES_BUG_URL'
'&title=$errorTitle'
'&title=$issueTitle'
'&description=$description';
final Uri reportUri = Uri.parse(githubIssueUrl);
try {
await launchUrl(reportUri, mode: LaunchMode.externalApplication);
} catch (e) {
if (kDebugMode) logger.warning('Error launching URL: $e');
if (kDebugMode) {
logger.warning('Error launching URL: $e');
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error opening issue tracker: $e')),
);

View File

@@ -744,26 +744,26 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
url: "https://pub.dev"
source: hosted
version: "11.0.1"
version: "10.0.9"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev"
source: hosted
version: "3.0.10"
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
version: "3.0.1"
lints:
dependency: transitive
description:
@@ -1301,10 +1301,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev"
source: hosted
version: "0.7.6"
version: "0.7.4"
timing:
dependency: transitive
description:
@@ -1413,10 +1413,10 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.1.4"
version:
dependency: "direct main"
description: