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 ecf0800..f7550a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 6.0.0
+- Updated internal libraries.
+- Bumped minimum Dart SDK to 3.0.
+- Added `MultipartFileRecreatable` 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:** `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/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
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/multipart_file_recreatable.dart b/lib/src/multipart_file_recreatable.dart
index 093324b..768380e 100644
--- a/lib/src/multipart_file_recreatable.dart
+++ b/lib/src/multipart_file_recreatable.dart
@@ -4,21 +4,39 @@ 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,
+ 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,
- this.filePath, {
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,
MediaType? contentType,
+ Map>? headers,
}) {
filename ??= p.basename(filePath);
final file = File(filePath);
@@ -27,15 +45,23 @@ class MultipartFileRecreatable extends MultipartFile {
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..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 {
@@ -35,7 +38,7 @@ class RetryInterceptor extends Interceptor {
'retryableExtraStatuses',
);
}
- if(retries < 0) {
+ if (retries < 0) {
throw ArgumentError(
'[retries] cannot be less than 0',
'retries',
@@ -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 9ea5827..c5d3e80 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: 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
documentation: https://github.com/rodion-m/dio_smart_retry#contents
environment:
- sdk: '>=2.12.0 <3.0.0'
+ sdk: '>=3.0.0 <4.0.0'
dependencies:
- dio: ^5.0.0
+ dio: ^5.3.3
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
- 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;
}