retry on HttpException (#34526)
diff --git a/packages/flutter_tools/lib/src/base/io.dart b/packages/flutter_tools/lib/src/base/io.dart
index a32f27c..0250dbd 100644
--- a/packages/flutter_tools/lib/src/base/io.dart
+++ b/packages/flutter_tools/lib/src/base/io.dart
@@ -48,6 +48,7 @@
HttpClientRequest,
HttpClientResponse,
HttpClientResponseCompressionState,
+ HttpException,
HttpHeaders,
HttpRequest,
HttpServer,
diff --git a/packages/flutter_tools/lib/src/base/net.dart b/packages/flutter_tools/lib/src/base/net.dart
index 28c7194..046929d 100644
--- a/packages/flutter_tools/lib/src/base/net.dart
+++ b/packages/flutter_tools/lib/src/base/net.dart
@@ -64,6 +64,9 @@
} on SocketException catch (error) {
printTrace('Download error: $error');
return null;
+ } on HttpException catch (error) {
+ printTrace('Download error: $error');
+ return null;
}
final HttpClientResponse response = await request.close();
// If we're making a HEAD request, we're only checking to see if the URL is
diff --git a/packages/flutter_tools/test/base/net_test.dart b/packages/flutter_tools/test/base/net_test.dart
index fc7a29e..c38437a 100644
--- a/packages/flutter_tools/test/base/net_test.dart
+++ b/packages/flutter_tools/test/base/net_test.dart
@@ -105,6 +105,32 @@
),
});
+testUsingContext('retry from HttpException', () async {
+ String error;
+ FakeAsync().run((FakeAsync time) {
+ fetchUrl(Uri.parse('http://example.invalid/')).then((List<int> value) {
+ error = 'test completed unexpectedly';
+ }, onError: (dynamic exception) {
+ error = 'test failed unexpectedly: $exception';
+ });
+ expect(testLogger.statusText, '');
+ time.elapse(const Duration(milliseconds: 10000));
+ expect(testLogger.statusText,
+ 'Download failed -- attempting retry 1 in 1 second...\n'
+ 'Download failed -- attempting retry 2 in 2 seconds...\n'
+ 'Download failed -- attempting retry 3 in 4 seconds...\n'
+ 'Download failed -- attempting retry 4 in 8 seconds...\n',
+ );
+ });
+ expect(testLogger.errorText, isEmpty);
+ expect(error, isNull);
+ expect(testLogger.traceText, contains('Download error: HttpException'));
+ }, overrides: <Type, Generator>{
+ HttpClientFactory: () => () => MockHttpClientThrowing(
+ const io.HttpException('test exception handling'),
+ ),
+ });
+
testUsingContext('max attempts', () async {
String error;
List<int> actualResult;