From ffc524fb62e53edf9fc7910852e404a20f11889b Mon Sep 17 00:00:00 2001 From: Deepak Bhagat Date: Sun, 28 Jun 2026 03:53:18 +0530 Subject: [PATCH] fix: guard null content in saveToDownloads to prevent crash Replace the force-unwrap content! with an explicit null guard so a null content (e.g. empty/failed response body) shows a friendly snackbar instead of throwing 'Null check operator used on a null value'. Add a regression test covering null content. Closes #1704 --- lib/utils/save_utils.dart | 23 ++++++++++++----------- test/utils/save_utils_test.dart | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib/utils/save_utils.dart b/lib/utils/save_utils.dart index 6370ae62d5..8fec746ef3 100644 --- a/lib/utils/save_utils.dart +++ b/lib/utils/save_utils.dart @@ -31,18 +31,19 @@ Future saveToDownloads( String? name, }) async { var message = ""; - var path = await getFileDownloadpath( - name, - ext ?? getFileExtension(mimeType), - ); + var path = await getFileDownloadpath(name, ext ?? getFileExtension(mimeType)); if (path != null) { - try { - await saveFile(path, content!); - var sp = getShortPath(path); - message = 'Saved to $sp'; - } catch (e) { - debugPrint("$e"); - message = "An error occurred while saving file."; + if (content == null) { + message = "No content available to save."; + } else { + try { + await saveFile(path, content); + var sp = getShortPath(path); + message = 'Saved to $sp'; + } catch (e) { + debugPrint("$e"); + message = "An error occurred while saving file."; + } } } else { message = "Unable to determine the download path."; diff --git a/test/utils/save_utils_test.dart b/test/utils/save_utils_test.dart index 039d0dc8e0..b8197ef98f 100644 --- a/test/utils/save_utils_test.dart +++ b/test/utils/save_utils_test.dart @@ -123,6 +123,28 @@ void main() { expect(find.byType(SnackBar), findsOneWidget); }); + testWidgets('saveToDownloads handles null content without crashing', ( + tester, + ) async { + final scaffoldKey = GlobalKey(); + await tester.pumpWidget( + MaterialApp( + scaffoldMessengerKey: scaffoldKey, + home: Scaffold(body: Container()), + ), + ); + + final sm = scaffoldKey.currentState!; + + await tester.runAsync(() async { + await saveToDownloads(sm, content: null, mimeType: 'text/plain'); + }); + + // Wait for snackbar to appear + await tester.pump(); + expect(find.byType(SnackBar), findsOneWidget); + }); + testWidgets('saveAndShowDialog executes', (tester) async { await tester.pumpWidget( MaterialApp(