From a579ca73b91fa94110395c943983ebf5b4cc909c Mon Sep 17 00:00:00 2001 From: Gaurav Saini Date: Mon, 23 Mar 2026 21:19:30 +1100 Subject: [PATCH] fix: handle autocomplete error gracefully in search field (#1950) When the autocomplete provider throws (e.g., network error or SnapDataNotFoundException), the search field now returns an empty options list instead of crashing the application. --- .../app_center/lib/search/search_field.dart | 7 ++++- .../app_center/test/search_field_test.dart | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/app_center/lib/search/search_field.dart b/packages/app_center/lib/search/search_field.dart index bb6d54f19..f0ac97abc 100644 --- a/packages/app_center/lib/search/search_field.dart +++ b/packages/app_center/lib/search/search_field.dart @@ -60,7 +60,12 @@ class _SearchFieldState extends ConsumerState { return RawAutocomplete( optionsBuilder: (query) async { ref.read(queryProvider.notifier).state = query.text; - final options = await ref.watch(autoCompleteProvider.future); + final AutoCompleteOptions options; + try { + options = await ref.watch(autoCompleteProvider.future); + } on Exception { + return []; + } if (options.snaps.isEmpty && options.debs.isEmpty) return []; _optionsAvailable = true; final snapOptions = options.snaps diff --git a/packages/app_center/test/search_field_test.dart b/packages/app_center/test/search_field_test.dart index e981c858b..552862d33 100644 --- a/packages/app_center/test/search_field_test.dart +++ b/packages/app_center/test/search_field_test.dart @@ -222,4 +222,33 @@ void main() { verifyNever(mockSelectedCallback(any)); }); }); + + group('error handling', () { + testWidgets('gracefully handles autocomplete error', (tester) async { + await tester.pumpApp( + (_) => ProviderScope( + overrides: [ + snapSearchProvider.overrideWith( + (ref, searchParameters) => + Stream.error(Exception('Network error')), + ), + appstreamSearchProvider + .overrideWith((ref, query) => Stream.value([])), + ], + child: SearchField( + onSearch: (_) {}, + onSnapSelected: (_) {}, + onDebSelected: (_) {}, + searchFocus: FocusNode(), + ), + ), + ); + + final textField = find.byType(TextField); + await tester.enterText(textField, 'test'); + await tester.pumpAndSettle(); + + expect(find.byType(TextField), findsOneWidget); + }); + }); }