From b77af132442bf3266ccf11b50ce909711455db3a Mon Sep 17 00:00:00 2001 From: "ipcjs.mac" Date: Wed, 24 Aug 2022 20:41:12 +0800 Subject: [PATCH 1/3] fix(web): fix 'Future already completed' error when connectTimeout was set. Closes #1536 --- dio/lib/src/adapters/browser_adapter.dart | 26 ++++++++++++++++++----- example_flutter_app/lib/http.dart | 4 +++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/dio/lib/src/adapters/browser_adapter.dart b/dio/lib/src/adapters/browser_adapter.dart index 1dc1c1af2..36cf72184 100644 --- a/dio/lib/src/adapters/browser_adapter.dart +++ b/dio/lib/src/adapters/browser_adapter.dart @@ -61,12 +61,13 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { ); }); - bool haveSent = false; + Timer? connectTimeoutTimer; if (options.connectTimeout > 0) { - Future.delayed(Duration(milliseconds: options.connectTimeout)).then( - (value) { - if (!haveSent) { + connectTimeoutTimer = Timer( + Duration(milliseconds: options.connectTimeout), + () { + if (!completer.isCompleted) { completer.completeError( DioError( requestOptions: options, @@ -76,6 +77,9 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { StackTrace.current, ); xhr.abort(); + } else { + print( + 'Warn: connectTimeout is triggered after fetch has completed.'); } }, ); @@ -83,7 +87,12 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { int sendStart = 0; xhr.upload.onProgress.listen((event) { - haveSent = true; + // This event will only be triggered if a request body exists. + if (connectTimeoutTimer != null) { + connectTimeoutTimer!.cancel(); + connectTimeoutTimer = null; + } + if (options.sendTimeout > 0) { if (sendStart == 0) { sendStart = DateTime.now().millisecondsSinceEpoch; @@ -111,6 +120,11 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { int receiveStart = 0; xhr.onProgress.listen((event) { + if (connectTimeoutTimer != null) { + connectTimeoutTimer!.cancel(); + connectTimeoutTimer = null; + } + if (options.receiveTimeout > 0) { if (receiveStart == 0) { receiveStart = DateTime.now().millisecondsSinceEpoch; @@ -136,6 +150,7 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { }); xhr.onError.first.then((_) { + connectTimeoutTimer?.cancel(); // Unfortunately, the underlying XMLHttpRequest API doesn't expose any // specific information about the error itself. completer.completeError( @@ -150,6 +165,7 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { cancelFuture?.then((err) { if (xhr.readyState < 4 && xhr.readyState > 0) { + connectTimeoutTimer?.cancel(); try { xhr.abort(); } catch (e) { diff --git a/example_flutter_app/lib/http.dart b/example_flutter_app/lib/http.dart index b7b6e953e..bb4f8a1d2 100644 --- a/example_flutter_app/lib/http.dart +++ b/example_flutter_app/lib/http.dart @@ -1,3 +1,5 @@ import 'package:dio/dio.dart'; -var dio = Dio(); +var dio = Dio(BaseOptions( + connectTimeout: 3000, +)); From 4748a70e9985c194558e41d47cd155e27259c24c Mon Sep 17 00:00:00 2001 From: "ipcjs.mac" Date: Thu, 20 Oct 2022 12:20:24 +0800 Subject: [PATCH 2/3] remove `print()` --- dio/lib/src/adapters/browser_adapter.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dio/lib/src/adapters/browser_adapter.dart b/dio/lib/src/adapters/browser_adapter.dart index 36cf72184..5d047f7ad 100644 --- a/dio/lib/src/adapters/browser_adapter.dart +++ b/dio/lib/src/adapters/browser_adapter.dart @@ -78,8 +78,7 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { ); xhr.abort(); } else { - print( - 'Warn: connectTimeout is triggered after fetch has completed.'); + // connectTimeout is triggered after fetch has completed. } }, ); @@ -97,8 +96,7 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { if (sendStart == 0) { sendStart = DateTime.now().millisecondsSinceEpoch; } - var t = DateTime.now().millisecondsSinceEpoch; - print(t - sendStart); + final t = DateTime.now().millisecondsSinceEpoch; if (t - sendStart > options.sendTimeout) { completer.completeError( DioError( From 732af80cf509e0291eda8a6d83e4267b3af101f4 Mon Sep 17 00:00:00 2001 From: "ipcjs.mac" Date: Thu, 20 Oct 2022 12:22:29 +0800 Subject: [PATCH 3/3] fix typo... --- dio/lib/src/adapters/browser_adapter.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dio/lib/src/adapters/browser_adapter.dart b/dio/lib/src/adapters/browser_adapter.dart index 5d047f7ad..a994d9c90 100644 --- a/dio/lib/src/adapters/browser_adapter.dart +++ b/dio/lib/src/adapters/browser_adapter.dart @@ -78,7 +78,7 @@ class BrowserHttpClientAdapter implements HttpClientAdapter { ); xhr.abort(); } else { - // connectTimeout is triggered after fetch has completed. + // connectTimeout is triggered after the fetch has been completed. } }, );