From 074d4283e8d65d6d3813ab94cd0ed11e939c9a7f Mon Sep 17 00:00:00 2001 From: hgraceb <38378650+hgraceb@users.noreply.github.com> Date: Wed, 2 Aug 2023 18:37:07 +0800 Subject: [PATCH] Fix for Dio.download not cleaning the file on data handling error (#1915) ### New Pull Request Checklist - [x] I have read the [Documentation](https://pub.dev/documentation/dio/latest/) - [x] I have searched for a similar pull request in the [project](https://github.com/cfug/dio/pulls) and found none - [x] I have updated this branch with the latest `main` branch to avoid conflicts (via merge from master or rebase) - [x] I have added the required tests to prove the fix/feature I'm adding - [x] I have updated the documentation (if necessary) - [x] I have run the tests without failures - [x] I have updated the `CHANGELOG.md` in the corresponding package ### Additional context and info (if any) --------- Signed-off-by: hgraceb <38378650+hgraceb@users.noreply.github.com> Co-authored-by: Flop --- dio/CHANGELOG.md | 1 + dio/lib/src/dio/dio_for_native.dart | 11 ++++++-- dio/test/download_test.dart | 43 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/dio/CHANGELOG.md b/dio/CHANGELOG.md index 75fad78ed..ac861c9e4 100644 --- a/dio/CHANGELOG.md +++ b/dio/CHANGELOG.md @@ -6,6 +6,7 @@ See the [Migration Guide][] for the complete breaking changes list.** ## Unreleased - Revert removed `download` for `DioMixin`. +- Fix for `Dio.download` not cleaning the file on data handling error. ## 5.3.1 diff --git a/dio/lib/src/dio/dio_for_native.dart b/dio/lib/src/dio/dio_for_native.dart index 521a813e0..d16fa4124 100644 --- a/dio/lib/src/dio/dio_for_native.dart +++ b/dio/lib/src/dio/dio_for_native.dart @@ -117,9 +117,9 @@ class DioForNative with DioMixin implements Dio { if (!closed) { closed = true; await asyncWrite; - await raf.close(); + await raf.close().catchError((_) => raf); if (deleteOnError && file.existsSync()) { - await file.delete(); + await file.delete().catchError((_) => file); } } } @@ -140,6 +140,11 @@ class DioForNative with DioMixin implements Dio { }).catchError((Object e) async { try { await subscription.cancel(); + closed = true; + await raf.close().catchError((_) => raf); + if (deleteOnError && file.existsSync()) { + await file.delete().catchError((_) => file); + } } finally { completer.completeError( DioMixin.assureDioException(e, response.requestOptions), @@ -151,7 +156,7 @@ class DioForNative with DioMixin implements Dio { try { await asyncWrite; closed = true; - await raf.close(); + await raf.close().catchError((_) => raf); completer.complete(response); } catch (e) { completer.completeError( diff --git a/dio/test/download_test.dart b/dio/test/download_test.dart index cdc0e4d50..334af34d2 100644 --- a/dio/test/download_test.dart +++ b/dio/test/download_test.dart @@ -94,6 +94,49 @@ void main() { ); }); + test('delete on error', () async { + const savePath = 'test/_download_test.md'; + final f = File(savePath)..createSync(recursive: true); + expect(f.existsSync(), isTrue); + + final dio = Dio()..options.baseUrl = serverUrl.toString(); + await expectLater( + dio + .download( + '/download', + savePath, + deleteOnError: true, + onReceiveProgress: (count, total) => throw AssertionError(), + ) + .catchError((e) => throw (e as DioException).error!), + throwsA(isA()), + ); + expect(f.existsSync(), isFalse); + }); + + test('delete on cancel', () async { + const savePath = 'test/_download_test.md'; + final f = File(savePath)..createSync(recursive: true); + expect(f.existsSync(), isTrue); + + final cancelToken = CancelToken(); + final dio = Dio()..options.baseUrl = serverUrl.toString(); + await expectLater( + dio + .download( + '/download', + savePath, + deleteOnError: true, + cancelToken: cancelToken, + onReceiveProgress: (count, total) => cancelToken.cancel(), + ) + .catchError((e) => throw (e as DioException).type), + throwsA(DioExceptionType.cancel), + ); + await Future.delayed(const Duration(milliseconds: 100)); + expect(f.existsSync(), isFalse); + }); + test('`savePath` types', () async { final testPath = p.join(Directory.systemTemp.path, 'dio', 'testPath');