improved error logging and handling

This commit is contained in:
Fabian Freund
2026-01-21 11:07:23 +01:00
parent f648c43441
commit dc4a5a9c85
35 changed files with 242 additions and 115 deletions
@@ -29,6 +29,7 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart';
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/geckoview/features/bookmarks/domain/entities/bookmark_item.dart';
import 'package:weblibre/features/geckoview/features/bookmarks/domain/providers/bookmarks.dart';
@@ -405,7 +406,8 @@ class BookmarkListScreen extends HookConsumerWidget {
if (context.mounted) {
showInfoMessage(context, 'Imported $count bookmarks successfully');
}
} catch (e) {
} catch (e, s) {
logger.e('Bookmark import failed', error: e, stackTrace: s);
if (context.mounted) {
showErrorMessage(context, 'Import failed: $e');
}
@@ -454,7 +456,8 @@ class BookmarkListScreen extends HookConsumerWidget {
if (context.mounted) {
showInfoMessage(context, 'Bookmarks exported successfully');
}
} catch (e) {
} catch (e, s) {
logger.e('Bookmark export failed', error: e, stackTrace: s);
if (context.mounted) {
showErrorMessage(context, 'Export failed: $e');
}
@@ -22,6 +22,7 @@ import 'dart:async';
import 'package:nullability/nullability.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:rxdart/rxdart.dart';
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/data/models/received_intent_parameter.dart';
import 'package:weblibre/features/app_widget/domain/services/home_widget.dart';
@@ -67,7 +68,10 @@ class EngineBoundIntentStream extends _$EngineBoundIntentStream {
appWidgetLaunchStream.transform(_contentParserTransformer),
]).listen(
controller.add,
onError: controller.addError,
onError: (Object error, StackTrace stackTrace) {
logger.e('Intent stream error', error: error, stackTrace: stackTrace);
controller.addError(error, stackTrace);
},
onDone: controller.close,
);
@@ -34,7 +34,7 @@ final class EngineBoundIntentStreamProvider
}
String _$engineBoundIntentStreamHash() =>
r'ab9804f97e0222b2306683d2fcfa71d3d57ecd21';
r'618eb6431da93989de6f1780cba2993458b0014e';
abstract class _$EngineBoundIntentStream
extends $StreamNotifier<SharedContent> {
@@ -302,7 +302,7 @@ class _BrowserViewState extends ConsumerState<BrowserView>
await router.push(route.location);
} else {
throw UnimplementedError();
throw UnimplementedError('Unknown quick action shortcut type');
}
}
});
@@ -21,6 +21,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/clear_site_data_dialog.dart';
import 'package:weblibre/utils/ui_helper.dart';
@@ -163,7 +164,8 @@ class ClearSiteDataSection extends HookConsumerWidget {
if (context.mounted) {
showInfoMessage(context, 'Site data cleared');
}
} catch (e) {
} catch (e, s) {
logger.e('Failed to clear site data', error: e, stackTrace: s);
if (context.mounted) {
showErrorMessage(context, 'Failed to clear site data: $e');
}
@@ -20,6 +20,7 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:skeletonizer/skeletonizer.dart';
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart';
import 'package:weblibre/features/geckoview/features/browser/domain/repositories/tracking_protection.dart';
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/sheets/tracking_protection_provider.dart';
@@ -102,7 +103,8 @@ class _TrackingProtectionTile extends ConsumerWidget {
// Reload tab to apply changes
await ref.read(selectedTabSessionProvider).reload();
} catch (e) {
} catch (e, s) {
logger.e('Failed to toggle tracking protection', error: e, stackTrace: s);
if (context.mounted) {
showErrorMessage(context, 'Failed to toggle tracking protection: $e');
}
@@ -82,7 +82,7 @@ class _TabDraggable extends HookConsumerWidget {
sourceSearchQuery: switch (entity) {
DefaultTabEntity _ => null,
final SearchResultTabEntity entity => entity.searchQuery,
TabTreeEntity _ => throw UnimplementedError(),
TabTreeEntity _ => throw UnimplementedError('TabTreeEntity not implemented in tab grid view'),
},
);
}, [entity.tabId, activeTab, suggestedContainerId]);
@@ -83,7 +83,7 @@ class _TabDraggable extends HookConsumerWidget {
sourceSearchQuery: switch (entity) {
DefaultTabEntity _ => null,
final SearchResultTabEntity entity => entity.searchQuery,
TabTreeEntity _ => throw UnimplementedError(),
TabTreeEntity _ => throw UnimplementedError('TabTreeEntity not implemented in tab list view'),
},
);
}, [entity.tabId, activeTab, suggestedContainerId]);
@@ -7,6 +7,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:weblibre/core/logger.dart';
import 'package:weblibre/core/routing/routes.dart';
import 'package:weblibre/features/geckoview/domain/providers.dart';
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
@@ -484,7 +485,8 @@ class TabViewHeader extends HookConsumerWidget {
: 'Container data cleared. ${tabs.length} tab(s) closed.',
);
}
} catch (e) {
} catch (e, s) {
logger.e('Failed to clear container data', error: e, stackTrace: s);
if (context.mounted) {
ui_helper.showErrorMessage(
context,
@@ -171,7 +171,7 @@ class Section extends MultiSliver {
VisitType.download => const Text('Download'),
VisitType.framedLink => const Text('Frame'),
VisitType.reload => const Text('Page Reload'),
VisitType.bookmark => throw UnimplementedError(),
VisitType.bookmark => throw UnimplementedError('VisitType.bookmark chip display not implemented'),
},
),
Chip(
@@ -374,7 +374,7 @@ class HistoryScreen extends HookConsumerWidget {
VisitType.download => const Text('Downloads'),
VisitType.framedLink => const Text('Frames'),
VisitType.reload => const Text('Page Reloads'),
VisitType.bookmark => throw UnimplementedError(),
VisitType.bookmark => throw UnimplementedError('VisitType.bookmark filter not implemented'),
},
),
),