From 9e79ba2057a0e40a20490624723425741bad47ab Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Tue, 2 May 2023 11:53:03 +0200 Subject: [PATCH 1/6] Add MultipartFileRecreatable.fromBytes + plugin improvements --- CHANGELOG.md | 12 +++++ lib/src/multipart_file_recreatable.dart | 60 ++++++++++++++++++------- lib/src/retry_interceptor.dart | 2 +- pubspec.yaml | 12 ++--- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf0800..18ebcbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 5.1.0 +- Updated internal libraries. +- Bumped minimum Dart SDK to 2.17. +- Added `MultipartFileRecreatablep documentation. +- Refactors static constructors to factories. +- Adds a new `MultipartFileRecreatable.fromBytes` factory compatible with web. +- Added a new `headers` parameter. +- You can now read the file's content with `MultipartFileRecreatable.data`. +- **Breaking:** Renamed `filename` to `fileName`. +- **Breaking:** `fileName` is now a named parameter. +- **Breaking:** Removed `MultipartFileRecreatable.filePath`. + ## 5.0.0 - Add supporting of the new dio 5.+ diff --git a/lib/src/multipart_file_recreatable.dart b/lib/src/multipart_file_recreatable.dart index 093324b..5e5789d 100644 --- a/lib/src/multipart_file_recreatable.dart +++ b/lib/src/multipart_file_recreatable.dart @@ -4,38 +4,64 @@ import 'package:dio/dio.dart'; import 'package:http_parser/http_parser.dart'; import 'package:path/path.dart' as p; +/// Creates an instance of [MultipartFile] that can be recreated and reused. class MultipartFileRecreatable extends MultipartFile { + /// Default constructor. MultipartFileRecreatable( - Stream> stream, - int length, - String? filename, - this.filePath, { + super.stream, + super.length, { + super.filename, + super.contentType, + super.headers, + }) : data = stream; + + /// Creates a [MultipartFileRecreatable] object with [bytes]. + factory MultipartFileRecreatable.fromBytes( + List bytes, { + String? fileName, MediaType? contentType, - }) : super(stream, length, filename: filename, contentType: contentType); - final String filePath; + Map>? headers, + }) { + return MultipartFileRecreatable( + Stream.fromIterable(>[bytes]), + bytes.length, + filename: fileName, + contentType: contentType, + headers: headers, + ); + } - // ignore: prefer_constructors_over_static_methods - static MultipartFileRecreatable fromFileSync( + /// Creates a [MultipartFileRecreatable] object from a [File] in [filePath]. + factory MultipartFileRecreatable.fromFileSync( String filePath, { - String? filename, + String? fileName, MediaType? contentType, + Map>? headers, }) { - filename ??= p.basename(filePath); + fileName ??= p.basename(filePath); final file = File(filePath); final length = file.lengthSync(); final stream = file.openRead(); return MultipartFileRecreatable( stream, length, - filename, - filePath, + filename: fileName, contentType: contentType, + headers: headers, ); } - MultipartFileRecreatable recreate() => fromFileSync( - filePath, - filename: filename, - contentType: contentType, - ); + /// The stream that will emit the file's contents. + final Stream> data; + + /// Recreates the [MultipartFileRecreatable] object. + MultipartFileRecreatable recreate() { + return MultipartFileRecreatable( + data, + length, + filename: filename, + contentType: contentType, + headers: headers, + ); + } } diff --git a/lib/src/retry_interceptor.dart b/lib/src/retry_interceptor.dart index 6950a7e..4c5b0c8 100644 --- a/lib/src/retry_interceptor.dart +++ b/lib/src/retry_interceptor.dart @@ -35,7 +35,7 @@ class RetryInterceptor extends Interceptor { 'retryableExtraStatuses', ); } - if(retries < 0) { + if (retries < 0) { throw ArgumentError( '[retries] cannot be less than 0', 'retries', diff --git a/pubspec.yaml b/pubspec.yaml index 9ea5827..746804a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,20 +1,20 @@ name: dio_smart_retry description: Retry library for Dio and Dio package made with love. By default, the request will be retried only for appropriate retryable http statuses. -version: 5.0.0 +version: 5.1.0 repository: https://github.com/rodion-m/dio_smart_retry issue_tracker: https://github.com/rodion-m/dio_smart_retry/issues homepage: https://github.com/rodion-m/dio_smart_retry documentation: https://github.com/rodion-m/dio_smart_retry#contents environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.17.0 <3.0.0' dependencies: - dio: ^5.0.0 + dio: ^5.1.1 http_parser: ^4.0.2 - path: ^1.8.2 + path: ^1.8.3 dev_dependencies: - dart_code_metrics: ^5.6.0 - test: ^1.23.1 + dart_code_metrics: ^5.7.2 + test: ^1.24.2 very_good_analysis: ^4.0.0+1 From e4aa08c76b54bd1a3e84253e6ba7a963fe45b82f Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Tue, 2 May 2023 11:55:35 +0200 Subject: [PATCH 2/6] Fix changelog format --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18ebcbd..0636fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## 5.1.0 - Updated internal libraries. - Bumped minimum Dart SDK to 2.17. -- Added `MultipartFileRecreatablep documentation. +- Added `MultipartFileRecreatable` documentation. - Refactors static constructors to factories. - Adds a new `MultipartFileRecreatable.fromBytes` factory compatible with web. - Added a new `headers` parameter. From 4ceabb0860e2c45dd30f5625accf1ef3308cce95 Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Tue, 2 May 2023 11:59:27 +0200 Subject: [PATCH 3/6] Revert `fileName` changes --- CHANGELOG.md | 3 +-- lib/src/multipart_file_recreatable.dart | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0636fd2..5c439fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,7 @@ - Adds a new `MultipartFileRecreatable.fromBytes` factory compatible with web. - Added a new `headers` parameter. - You can now read the file's content with `MultipartFileRecreatable.data`. -- **Breaking:** Renamed `filename` to `fileName`. -- **Breaking:** `fileName` is now a named parameter. +- **Breaking:** `filename` is now a named parameter. - **Breaking:** Removed `MultipartFileRecreatable.filePath`. ## 5.0.0 diff --git a/lib/src/multipart_file_recreatable.dart b/lib/src/multipart_file_recreatable.dart index 5e5789d..768380e 100644 --- a/lib/src/multipart_file_recreatable.dart +++ b/lib/src/multipart_file_recreatable.dart @@ -18,14 +18,14 @@ class MultipartFileRecreatable extends MultipartFile { /// Creates a [MultipartFileRecreatable] object with [bytes]. factory MultipartFileRecreatable.fromBytes( List bytes, { - String? fileName, + String? filename, MediaType? contentType, Map>? headers, }) { return MultipartFileRecreatable( Stream.fromIterable(>[bytes]), bytes.length, - filename: fileName, + filename: filename, contentType: contentType, headers: headers, ); @@ -34,18 +34,18 @@ class MultipartFileRecreatable extends MultipartFile { /// Creates a [MultipartFileRecreatable] object from a [File] in [filePath]. factory MultipartFileRecreatable.fromFileSync( String filePath, { - String? fileName, + String? filename, MediaType? contentType, Map>? headers, }) { - fileName ??= p.basename(filePath); + filename ??= p.basename(filePath); final file = File(filePath); final length = file.lengthSync(); final stream = file.openRead(); return MultipartFileRecreatable( stream, length, - filename: fileName, + filename: filename, contentType: contentType, headers: headers, ); From d3be51b4f52c2b3e464c9577691f0c8f661541d4 Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Thu, 26 Oct 2023 11:10:21 +0200 Subject: [PATCH 4/6] Update to latest versions --- .idea/dio_smart_retry.iml | 1 - .idea/misc.xml | 1 - CHANGELOG.md | 2 +- lib/src/default_retry_evaluator.dart | 8 ++++---- lib/src/retry_interceptor.dart | 19 +++++++++++++------ pubspec.yaml | 10 +++++----- test/multipart_retry_tests.dart | 6 +++--- test/override_retryable_statuses_test.dart | 4 ++-- 8 files changed, 28 insertions(+), 23 deletions(-) diff --git a/.idea/dio_smart_retry.iml b/.idea/dio_smart_retry.iml index 0df1d15..1676d1b 100644 --- a/.idea/dio_smart_retry.iml +++ b/.idea/dio_smart_retry.iml @@ -10,6 +10,5 @@ - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 639900d..6e86672 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c439fe..f6de517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## 5.1.0 - Updated internal libraries. -- Bumped minimum Dart SDK to 2.17. +- Bumped minimum Dart SDK to 3.0. - Added `MultipartFileRecreatable` documentation. - Refactors static constructors to factories. - Adds a new `MultipartFileRecreatable.fromBytes` factory compatible with web. diff --git a/lib/src/default_retry_evaluator.dart b/lib/src/default_retry_evaluator.dart index f22f06b..0f39b91 100644 --- a/lib/src/default_retry_evaluator.dart +++ b/lib/src/default_retry_evaluator.dart @@ -11,9 +11,9 @@ class DefaultRetryEvaluator { /// Returns true only if the response hasn't been cancelled /// or got a bad status code. // ignore: avoid-unused-parameters - FutureOr evaluate(DioError error, int attempt) { + FutureOr evaluate(DioException error, int attempt) { bool shouldRetry; - if (error.type == DioErrorType.badResponse) { + if (error.type == DioExceptionType.badResponse) { final statusCode = error.response?.statusCode; if (statusCode != null) { shouldRetry = isRetryable(statusCode); @@ -21,8 +21,8 @@ class DefaultRetryEvaluator { shouldRetry = true; } } else { - shouldRetry = - error.type != DioErrorType.cancel && error.error is! FormatException; + shouldRetry = error.type != DioExceptionType.cancel && + error.error is! FormatException; } currentAttempt = attempt; return shouldRetry; diff --git a/lib/src/retry_interceptor.dart b/lib/src/retry_interceptor.dart index 4c5b0c8..c90f05a 100644 --- a/lib/src/retry_interceptor.dart +++ b/lib/src/retry_interceptor.dart @@ -6,7 +6,10 @@ import 'package:dio_smart_retry/src/http_status_codes.dart'; import 'package:dio_smart_retry/src/multipart_file_recreatable.dart'; import 'package:dio_smart_retry/src/retry_not_supported_exception.dart'; -typedef RetryEvaluator = FutureOr Function(DioError error, int attempt); +typedef RetryEvaluator = FutureOr Function( + DioException error, + int attempt, +); /// An interceptor that will try to send failed request again class RetryInterceptor extends Interceptor { @@ -82,11 +85,11 @@ class RetryInterceptor extends Interceptor { /// Redirects to [DefaultRetryEvaluator.evaluate] /// with [defaultRetryableStatuses] - static final FutureOr Function(DioError error, int attempt) + static final FutureOr Function(DioException error, int attempt) defaultRetryEvaluator = DefaultRetryEvaluator(defaultRetryableStatuses).evaluate; - Future _shouldRetry(DioError error, int attempt) async { + Future _shouldRetry(DioException error, int attempt) async { try { return await _retryEvaluator(error, attempt); } catch (e) { @@ -105,7 +108,10 @@ class RetryInterceptor extends Interceptor { } @override - Future onError(DioError err, ErrorInterceptorHandler handler) async { + Future onError( + DioException err, + ErrorInterceptorHandler handler, + ) async { if (err.requestOptions.disableRetry) { return super.onError(err, handler); } @@ -135,7 +141,7 @@ class RetryInterceptor extends Interceptor { requestOptions = _recreateOptions(err.requestOptions); } on RetryNotSupportedException catch (e) { return super.onError( - DioError(requestOptions: requestOptions, error: e), + DioException(requestOptions: requestOptions, error: e), handler, ); } @@ -153,7 +159,7 @@ class RetryInterceptor extends Interceptor { await dio .fetch(requestOptions) .then((value) => handler.resolve(value)); - } on DioError catch (e) { + } on DioException catch (e) { super.onError(e, handler); } } @@ -191,6 +197,7 @@ class RetryInterceptor extends Interceptor { } var _multipartFileChecked = false; + void _printErrorIfRequestHasMultipartFile(RequestOptions options) { if (_multipartFileChecked) return; if (options.data is FormData) { diff --git a/pubspec.yaml b/pubspec.yaml index 746804a..795e260 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,14 +7,14 @@ homepage: https://github.com/rodion-m/dio_smart_retry documentation: https://github.com/rodion-m/dio_smart_retry#contents environment: - sdk: '>=2.17.0 <3.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: - dio: ^5.1.1 + dio: ^5.3.3 http_parser: ^4.0.2 path: ^1.8.3 dev_dependencies: - dart_code_metrics: ^5.7.2 - test: ^1.24.2 - very_good_analysis: ^4.0.0+1 + dart_code_metrics: ^5.7.6 + test: ^1.24.9 + very_good_analysis: ^5.1.0 diff --git a/test/multipart_retry_tests.dart b/test/multipart_retry_tests.dart index 69e70ad..dd31293 100644 --- a/test/multipart_retry_tests.dart +++ b/test/multipart_retry_tests.dart @@ -22,7 +22,7 @@ void main() { 'https://rodion-m.ru/mock/post500.php', data: formData, ); - } on DioError catch (error) { + } on DioException catch (error) { exception = error.error; } @@ -51,8 +51,8 @@ void main() { 'https://rodion-m.ru/mock/post500.php', data: formData, ); - } on DioError catch (error) { - if (error.type != DioErrorType.badResponse) { + } on DioException catch (error) { + if (error.type != DioExceptionType.badResponse) { rethrow; } } diff --git a/test/override_retryable_statuses_test.dart b/test/override_retryable_statuses_test.dart index b8dbe81..c35b620 100644 --- a/test/override_retryable_statuses_test.dart +++ b/test/override_retryable_statuses_test.dart @@ -20,8 +20,8 @@ void main() { try { await dio.get('https://mock.codes/400'); - } on DioError catch (error) { - if (error.type != DioErrorType.badResponse || + } on DioException catch (error) { + if (error.type != DioExceptionType.badResponse || error.response?.statusCode != 400) { rethrow; } From e6eab7f4cca24fba48e4cd9f3e0ed6610ad19f11 Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Thu, 26 Oct 2023 11:20:21 +0200 Subject: [PATCH 5/6] Update major version --- CHANGELOG.md | 6 +++--- pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6de517..f7550a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 5.1.0 +## 6.0.0 - Updated internal libraries. - Bumped minimum Dart SDK to 3.0. - Added `MultipartFileRecreatable` documentation. @@ -6,8 +6,8 @@ - Adds a new `MultipartFileRecreatable.fromBytes` factory compatible with web. - Added a new `headers` parameter. - You can now read the file's content with `MultipartFileRecreatable.data`. -- **Breaking:** `filename` is now a named parameter. -- **Breaking:** Removed `MultipartFileRecreatable.filePath`. +- **Breaking:** `MultipartFileRecreatable.filename` is now a named parameter to match `dio`. +- **Breaking:** Removed `MultipartFileRecreatable.filePath` since it was not being used internally. ## 5.0.0 - Add supporting of the new dio 5.+ diff --git a/pubspec.yaml b/pubspec.yaml index 795e260..c5d3e80 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: dio_smart_retry description: Retry library for Dio and Dio package made with love. By default, the request will be retried only for appropriate retryable http statuses. -version: 5.1.0 +version: 6.0.0 repository: https://github.com/rodion-m/dio_smart_retry issue_tracker: https://github.com/rodion-m/dio_smart_retry/issues homepage: https://github.com/rodion-m/dio_smart_retry From 9d7767b179edd822f13f5bf4c992b218282252cb Mon Sep 17 00:00:00 2001 From: Cristian Zazo Date: Thu, 26 Oct 2023 11:29:38 +0200 Subject: [PATCH 6/6] Update readme --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b0e70a9..6f81fb6 100644 --- a/README.md +++ b/README.md @@ -129,4 +129,30 @@ final formData = data: formData, ); ``` -See the full example in the test: https://github.com/rodion-m/dio_smart_retry/blob/63a3bddae8b5a0581c35c4ae5e973996561d9100/test/multipart_retry_tests.dart#L32-L61 \ No newline at end of file +See the full example in the test: https://github.com/rodion-m/dio_smart_retry/blob/63a3bddae8b5a0581c35c4ae5e973996561d9100/test/multipart_retry_tests.dart#L32-L61 + +## Migrating to 6.0 + +Version 6.0 introduces 2 breaking changes: +- `MultipartFileRecreatable.filename` is now a named parameter +- `MultipartFileRecreatable.filePath` is now removed + +To update to the latest version, if you were using the `MultipartFileRecreatable` constructor, remove the `filePath` parameter and change `filename` to a named parameter: + +Old: +```dart +return MultipartFileRecreatable( + stream, + length, + filename, + filePath, +); +``` +New: +```dart +return MultipartFileRecreatable( + stream, + length, + filename: filename, +); +``` \ No newline at end of file