improved error reporting
This commit is contained in:
parent
ec7e4ac2f2
commit
ffbf0bd8f2
15 changed files with 25 additions and 26 deletions
|
@ -32,7 +32,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
|
|||
final appliedModifier = await _applyDateModifierToEntry(userModifier);
|
||||
if (appliedModifier == null) {
|
||||
if (isValid && userModifier.action != DateEditAction.copyField) {
|
||||
await reportService.recordError('failed to get date for modifier=$userModifier, entry=$this', null);
|
||||
await reportService.recordError('failed to get date for modifier=$userModifier, entry=$this');
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ extension ExtraAvesEntryMetadataEdition on AvesEntry {
|
|||
final shiftedDate = date.add(Duration(seconds: appliedModifier.shiftSeconds!));
|
||||
editCreateDateXmp(descriptions, shiftedDate);
|
||||
} else {
|
||||
reportService.recordError('failed to parse XMP date=$xmpDate', null);
|
||||
reportService.recordError('failed to parse XMP date=$xmpDate');
|
||||
}
|
||||
}
|
||||
case DateEditAction.remove:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:aves/model/entry/entry.dart';
|
||||
import 'package:aves/model/metadata/catalog.dart';
|
||||
import 'package:aves/model/media/video/channel_layouts.dart';
|
||||
import 'package:aves/model/media/video/codecs.dart';
|
||||
import 'package:aves/model/media/video/profiles/aac.dart';
|
||||
import 'package:aves/model/media/video/profiles/h264.dart';
|
||||
import 'package:aves/model/media/video/profiles/hevc.dart';
|
||||
import 'package:aves/model/metadata/catalog.dart';
|
||||
import 'package:aves/ref/languages.dart';
|
||||
import 'package:aves/ref/locales.dart';
|
||||
import 'package:aves/ref/mime_types.dart';
|
||||
|
@ -99,7 +99,7 @@ class VideoMetadataFormatter {
|
|||
if (isDefined(dateString)) {
|
||||
dateMillis = parseVideoDate(dateString);
|
||||
if (dateMillis == null && !isAmbiguousDate(dateString)) {
|
||||
await reportService.recordError('getCatalogMetadata failed to parse date=$dateString for mimeType=${entry.mimeType} entry=$entry', null);
|
||||
await reportService.recordError('getCatalogMetadata failed to parse date=$dateString for mimeType=${entry.mimeType} entry=$entry');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class MediaStoreSource extends CollectionSource {
|
|||
final currentTimeZoneOffset = DateTime.now().timeZoneOffset.inMilliseconds;
|
||||
final catalogTimeZoneOffset = settings.catalogTimeZoneOffsetMillis;
|
||||
if (currentTimeZoneOffset != catalogTimeZoneOffset) {
|
||||
unawaited(reportService.recordError('Time zone offset change: $currentTimeZoneOffset -> $catalogTimeZoneOffset. Clear catalog metadata to get correct date/times.', null));
|
||||
unawaited(reportService.recordError('Time zone offset change: $currentTimeZoneOffset -> $catalogTimeZoneOffset. Clear catalog metadata to get correct date/times.'));
|
||||
await localMediaDb.clearDates();
|
||||
await localMediaDb.clearCatalogMetadata();
|
||||
settings.catalogTimeZoneOffsetMillis = currentTimeZoneOffset;
|
||||
|
@ -212,7 +212,7 @@ class MediaStoreSource extends CollectionSource {
|
|||
// TODO TLAD find duplication cause
|
||||
final duplicates = await localMediaDb.searchLiveDuplicates(EntryOrigins.mediaStoreContent, newEntries);
|
||||
if (duplicates.isNotEmpty) {
|
||||
unawaited(reportService.recordError(Exception('Loading entries yielded duplicates=${duplicates.join(', ')}'), StackTrace.current));
|
||||
unawaited(reportService.recordError(Exception('Loading entries yielded duplicates=${duplicates.join(', ')}')));
|
||||
// post-error cleanup
|
||||
await localMediaDb.removeIds(duplicates.map((v) => v.id).toSet());
|
||||
for (final duplicate in duplicates) {
|
||||
|
@ -325,7 +325,7 @@ class MediaStoreSource extends CollectionSource {
|
|||
// TODO TLAD find duplication cause
|
||||
final duplicates = await localMediaDb.searchLiveDuplicates(EntryOrigins.mediaStoreContent, newEntries);
|
||||
if (duplicates.isNotEmpty) {
|
||||
unawaited(reportService.recordError(Exception('Refreshing entries yielded duplicates=${duplicates.join(', ')}'), StackTrace.current));
|
||||
unawaited(reportService.recordError(Exception('Refreshing entries yielded duplicates=${duplicates.join(', ')}')));
|
||||
// post-error cleanup
|
||||
await localMediaDb.removeIds(duplicates.map((v) => v.id).toSet());
|
||||
for (final duplicate in duplicates) {
|
||||
|
|
|
@ -76,7 +76,7 @@ mixin TrashMixin on SourceBase {
|
|||
sourceEntry.trashDetails = _buildTrashDetails(id);
|
||||
newEntries.add(sourceEntry);
|
||||
} else {
|
||||
await reportService.recordError('Failed to recover untracked bin item at uri=$uri', null);
|
||||
await reportService.recordError('Failed to recover untracked bin item at uri=$uri');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -175,7 +175,7 @@ class Vaults extends ChangeNotifier {
|
|||
sourceEntry.origin = EntryOrigins.vault;
|
||||
newEntries.add(sourceEntry);
|
||||
} else {
|
||||
await reportService.recordError('Failed to recover untracked vault item at uri=$uri', null);
|
||||
await reportService.recordError('Failed to recover untracked vault item at uri=$uri');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,10 +6,8 @@ import 'package:aves/model/entry/extensions/props.dart';
|
|||
import 'package:aves/model/metadata/date_modifier.dart';
|
||||
import 'package:aves/services/common/services.dart';
|
||||
import 'package:aves_model/aves_model.dart';
|
||||
import 'package:aves_report/aves_report.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
abstract class MetadataEditService {
|
||||
Future<Map<String, dynamic>> rotate(AvesEntry entry, {required bool clockwise});
|
||||
|
@ -135,24 +133,22 @@ class PlatformMetadataEditService implements MetadataEditService {
|
|||
}
|
||||
}
|
||||
|
||||
StackTrace? _currentStack() => ReportService.buildReportStack(Trace.current(), level: 1);
|
||||
|
||||
// distinct exceptions to convince Crashlytics to split reports into distinct issues
|
||||
// The distinct debug statement is there to make the body unique, so that the methods are not merged at compile time.
|
||||
|
||||
Future<void> mp4LargeMoov(CustomPlatformException e) {
|
||||
debugPrint('mp4LargeMoov $e');
|
||||
return reportService.recordError(e, _currentStack());
|
||||
return reportService.recordError(e);
|
||||
}
|
||||
|
||||
Future<void> mp4LargeOther(CustomPlatformException e) {
|
||||
debugPrint('mp4LargeOther $e');
|
||||
return reportService.recordError(e, _currentStack());
|
||||
return reportService.recordError(e);
|
||||
}
|
||||
|
||||
Future<void> fileNotFound(CustomPlatformException e) {
|
||||
debugPrint('fileNotFound $e');
|
||||
return reportService.recordError(e, _currentStack());
|
||||
return reportService.recordError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -693,7 +693,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
|||
_mediaStoreSource.updateDerivedFilters();
|
||||
}
|
||||
|
||||
void _onError(String? error) => reportService.recordError(error, null);
|
||||
void _onError(String? error) => reportService.recordError(error);
|
||||
|
||||
void _onAppModeChanged() {
|
||||
final appMode = _appModeNotifier.value;
|
||||
|
|
|
@ -61,8 +61,8 @@ mixin SingleEntryEditorMixin on FeedbackMixin, PermissionAwareMixin {
|
|||
} else {
|
||||
showFeedback(context, FeedbackType.warn, l10n.genericFailureFeedback);
|
||||
}
|
||||
} catch (error, stack) {
|
||||
await reportService.recordError(error, stack);
|
||||
} catch (e, stack) {
|
||||
await reportService.recordError(e, stack);
|
||||
}
|
||||
source?.resumeMonitoring();
|
||||
}
|
||||
|
|
|
@ -96,8 +96,8 @@ mixin CastMixin {
|
|||
);
|
||||
debugPrint('cast: play entry=$entry');
|
||||
unawaited(renderer.play());
|
||||
} catch (error, stack) {
|
||||
await reportService.recordError(error, stack);
|
||||
} catch (e, stack) {
|
||||
await reportService.recordError(e, stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ abstract class ReportService {
|
|||
|
||||
Future<void> setCustomKeys(Map<String, Object> map);
|
||||
|
||||
Future<void> recordError(dynamic exception, StackTrace? stack);
|
||||
Future<void> recordError(dynamic exception, [StackTrace? stack]);
|
||||
|
||||
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class PlatformReportService extends ReportService {
|
|||
Future<void> log(String message) async => debugPrint('Report log with message=$message');
|
||||
|
||||
@override
|
||||
Future<void> recordError(dynamic exception, StackTrace? stack) async => debugPrint('Report error with exception=$exception, stack=$stack');
|
||||
Future<void> recordError(dynamic exception, [StackTrace? stack]) async => debugPrint('Report error with exception=$exception, stack=$stack');
|
||||
|
||||
@override
|
||||
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails) async => debugPrint('Report Flutter error with details=$flutterErrorDetails');
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:firebase_core/firebase_core.dart';
|
|||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
class PlatformReportService extends ReportService {
|
||||
FirebaseCrashlytics? get _instance {
|
||||
|
@ -65,11 +66,12 @@ class PlatformReportService extends ReportService {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> recordError(dynamic exception, StackTrace? stack) async {
|
||||
Future<void> recordError(dynamic exception, [StackTrace? stack]) async {
|
||||
if (exception is PlatformException && stack != null) {
|
||||
stack = ReportService.buildReportStack(stack, level: 2);
|
||||
}
|
||||
if (exception is! UnreportedStateError) {
|
||||
stack ??= ReportService.buildReportStack(Trace.current(), level: 1);
|
||||
return _instance?.recordError(exception, stack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ packages:
|
|||
source: hosted
|
||||
version: "1.10.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
|
||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
|||
# so that the transitive `path` gets upgraded to v1.8.3
|
||||
firebase_core: ">=2.10.0"
|
||||
firebase_crashlytics:
|
||||
stack_trace:
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints:
|
||||
|
|
|
@ -21,7 +21,7 @@ class FakeReportService extends ReportService {
|
|||
Future<void> setCustomKeys(Map<String, Object> map) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> recordError(dynamic exception, StackTrace? stack) => SynchronousFuture(null);
|
||||
Future<void> recordError(dynamic exception, [StackTrace? stack]) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails) => SynchronousFuture(null);
|
||||
|
|
Loading…
Reference in a new issue