Add stack trace logging and context.mounted check in buildSnackBar

codemagic-setup
Hank Grabowski 2023-04-20 16:26:11 -04:00
rodzic 3e70dcbd74
commit 32408b96c0
10 zmienionych plików z 61 dodań i 35 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import 'package:relatica/models/exec_error.dart';
import 'package:result_monad/result_monad.dart';
import '../../models/gallery_data.dart';
@ -55,10 +56,9 @@ class _MediaUploadsControlState extends State<MediaUploadsControl> {
.entryMediaItems.attachments
.addAll(newEntries)),
onError: (error) {
if (mounted) {
buildSnackbar(context,
'Error selecting attachments: $error');
}
buildSnackbar(context,
'Error selecting attachments: $error');
logError(error, _logger);
});
},
icon: const Icon(Icons.camera_alt),
@ -111,7 +111,7 @@ class _MediaUploadsControlState extends State<MediaUploadsControl> {
alignLabelWithHint: true,
border: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).backgroundColor,
color: Theme.of(context).colorScheme.background,
),
borderRadius: BorderRadius.circular(5.0),
),

Wyświetl plik

@ -3,8 +3,10 @@ import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart
import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import 'package:result_monad/result_monad.dart';
import '../globals.dart';
import '../models/exec_error.dart';
import '../models/user_notification.dart';
import '../routes.dart';
import '../services/connections_manager.dart';
@ -139,11 +141,11 @@ class NotificationControl extends StatelessWidget {
onPressed: manager == null
? null
: () async {
final result = await manager.markSeen(notification);
if (result.isFailure) {
buildSnackbar(context,
'Error marking notification: ${result.error}');
}
await manager.markSeen(notification).withError((error) {
buildSnackbar(
context, 'Error marking notification: $error');
logError(error, _logger);
});
},
icon: Icon(Icons.close_rounded)),
);

Wyświetl plik

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';
import 'package:relatica/models/exec_error.dart';
import 'package:result_monad/result_monad.dart';
import '../../globals.dart';
@ -102,6 +103,7 @@ class _InteractionsBarControlState extends State<InteractionsBarControl> {
});
}, onError: (error) {
buildSnackbar(context, 'Error resharing post by ${widget.entry.author}');
logError(error, _logger);
});
setState(() {
isProcessing = false;
@ -128,6 +130,7 @@ class _InteractionsBarControlState extends State<InteractionsBarControl> {
}, onError: (error) {
buildSnackbar(
context, 'Error un-resharing post by ${widget.entry.author}');
logError(error, _logger);
});
setState(() {
isProcessing = false;

Wyświetl plik

@ -1,4 +1,6 @@
import 'package:logging/logging.dart';
import 'package:result_monad/result_monad.dart';
import 'package:stack_trace/stack_trace.dart';
Result<T, ExecError> buildErrorResult<T>({
required ErrorType type,
@ -14,22 +16,28 @@ Result<T, ExecError> buildErrorResult<T>({
class ExecError {
final ErrorType type;
final String message;
final Trace trace;
ExecError({required this.type, this.message = ''});
ExecError({required this.type, this.message = '', Trace? trace})
: trace = trace ?? Trace.current(1);
ExecError copy({
ErrorType? type,
String? message,
Trace? trace,
}) =>
ExecError(
type: type ?? this.type,
message: message ?? this.message,
trace: trace ?? this.trace,
);
@override
String toString() {
return 'ExecError{type: $type, message: $message}';
}
String printStackTrace() => trace.terse.toString();
}
enum ErrorType {
@ -50,3 +58,8 @@ extension ExecErrorExtension<T, E> on Result<T, E> {
FutureResult<T, ExecError> execErrorCastAsync() async => execErrorCast();
}
void logError(ExecError error, Logger logger,
{Level logLevel = Level.INFO, String message = ''}) {
logger.log(logLevel, '$message $error\n${error.trace}');
}

Wyświetl plik

@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';
import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart';
import 'package:provider/provider.dart';
import 'package:result_monad/result_monad.dart';
import 'package:uuid/uuid.dart';
import '../controls/autocomplete/hashtag_autocomplete_options.dart';
@ -15,6 +16,7 @@ import '../controls/padding.dart';
import '../controls/standard_appbar.dart';
import '../controls/timeline/status_header_control.dart';
import '../globals.dart';
import '../models/exec_error.dart';
import '../models/group_data.dart';
import '../models/image_entry.dart';
import '../models/link_preview_data.dart';
@ -110,13 +112,8 @@ class _EditorScreenState extends State<EditorScreen> {
loaded = true;
});
}, onError: (error) {
if (context.mounted) {
buildSnackbar(
context,
'Error getting post for editing: $error',
);
}
_logger.severe('Error getting post for editing: $error');
buildSnackbar(context, 'Error getting post for editing: $error');
logError(error, _logger);
});
}
@ -152,20 +149,25 @@ class _EditorScreenState extends State<EditorScreen> {
isSubmitting = true;
});
final result = await manager.createNewStatus(
final result = await manager
.createNewStatus(
bodyText,
spoilerText: spoilerController.text,
inReplyToId: widget.parentId,
newMediaItems: newMediaItems,
existingMediaItems: existingMediaItems,
visibility: visibility,
);
)
.withError((error) {
buildSnackbar(context, 'Error posting: $error');
logError(error, _logger);
});
setState(() {
isSubmitting = false;
});
if (result.isFailure) {
buildSnackbar(context, 'Error posting: ${result.error}');
return;
}
@ -184,7 +186,8 @@ class _EditorScreenState extends State<EditorScreen> {
isSubmitting = true;
});
final result = await manager.editStatus(
final result = await manager
.editStatus(
widget.id,
bodyText,
spoilerText: spoilerController.text,
@ -192,13 +195,17 @@ class _EditorScreenState extends State<EditorScreen> {
newMediaItems: newMediaItems,
existingMediaItems: existingMediaItems,
newMediaItemVisibility: visibility,
);
)
.withError((error) {
buildSnackbar(context, 'Error updating $statusType: $error');
logError(error, _logger);
});
setState(() {
isSubmitting = false;
});
if (result.isFailure) {
buildSnackbar(context, 'Error Updating $statusType: ${result.error}');
return;
}
@ -468,6 +475,7 @@ class _EditorScreenState extends State<EditorScreen> {
if (mounted) {
buildSnackbar(
context, 'Error building link preview: $error');
logError(error, _logger);
}
});
},

Wyświetl plik

@ -27,10 +27,10 @@ class _GroupCreateScreenState extends State<GroupCreateScreen> {
final result = await manager.createGroup(groupTextController.text);
if (context.mounted) {
result.match(
onSuccess: (_) => context.canPop() ? context.pop() : null,
onError: (error) =>
buildSnackbar(context, 'Error trying to create new group: $error'),
);
onSuccess: (_) => context.canPop() ? context.pop() : null,
onError: (error) {
buildSnackbar(context, 'Error trying to create new group: $error');
});
}
}

Wyświetl plik

@ -46,9 +46,7 @@ class _GroupEditorScreenState extends State<GroupEditorScreen> {
allowNameEditing = false;
});
}, onError: (error) {
if (mounted) {
buildSnackbar(context, 'Error renaming group: $error');
}
buildSnackbar(context, 'Error renaming group: $error');
});
} else {
groupTextController.text = groupData.name;
@ -81,9 +79,7 @@ class _GroupEditorScreenState extends State<GroupEditorScreen> {
onSuccess: (_) => 'Removed $messageBase',
onError: (error) => 'Error removing $messageBase: $error',
);
if (context.mounted) {
buildSnackbar(context, message);
}
buildSnackbar(context, message);
}
}

Wyświetl plik

@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
Future<void> buildSnackbar(BuildContext context, String message,
{int durationSec = 3}) async {
if (!context.mounted) {
return;
}
final snackBar = SnackBar(
content: SelectableText(message),
duration: Duration(seconds: durationSec),

Wyświetl plik

@ -1140,7 +1140,7 @@ packages:
source: hosted
version: "1.11.0"
stack_trace:
dependency: transitive
dependency: "direct main"
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5

Wyświetl plik

@ -56,6 +56,7 @@ dependencies:
string_validator: ^0.3.0
device_preview: ^1.1.0
color_blindness: ^0.1.2
stack_trace: ^1.11.0
dev_dependencies:
flutter_test: