From 4ce2a7aa6d315e4ae7ae2f15dd2aafaea3d48428 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 5 Oct 2020 09:05:41 -0700 Subject: [PATCH] [flutter_tools] do not use IOSink for writing cache responses (#67231) Any File-derived IOSink may throw un-handleable async exceptions into the zone, see dart-lang/sdk#43663 . Instead, just write to a file with an append mode. --- packages/flutter_tools/lib/src/cache.dart | 15 +++++++++------ .../test/general.shard/artifact_updater_test.dart | 3 ++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart index dff213da72..196b5dbe07 100644 --- a/packages/flutter_tools/lib/src/cache.dart +++ b/packages/flutter_tools/lib/src/cache.dart @@ -1598,10 +1598,11 @@ class ArtifactUpdater { ); try { _ensureExists(tempFile.parent); - final IOSink ioSink = tempFile.openWrite(); - await _download(url, ioSink); - await ioSink.flush(); - await ioSink.close(); + if (tempFile.existsSync()) { + tempFile.deleteSync(); + } + await _download(url, tempFile); + if (!tempFile.existsSync()) { throw Exception('Did not find downloaded file ${tempFile.path}'); } @@ -1656,13 +1657,15 @@ class ArtifactUpdater { } /// Download bytes from [url], throwing non-200 responses as an exception. - Future _download(Uri url, IOSink ioSink) async { + Future _download(Uri url, File file) async { final HttpClientRequest request = await _httpClient.getUrl(url); final HttpClientResponse response = await request.close(); if (response.statusCode != HttpStatus.ok) { throw Exception(response.statusCode); } - await response.forEach(ioSink.add); + await response.forEach((List chunk) { + file.writeAsBytesSync(chunk, mode: FileMode.append); + }); } /// Create a temporary file and invoke [onTemporaryFile] with the file as diff --git a/packages/flutter_tools/test/general.shard/artifact_updater_test.dart b/packages/flutter_tools/test/general.shard/artifact_updater_test.dart index d96a6d72bd..f5741fed72 100644 --- a/packages/flutter_tools/test/general.shard/artifact_updater_test.dart +++ b/packages/flutter_tools/test/general.shard/artifact_updater_test.dart @@ -18,7 +18,7 @@ import 'package:mockito/mockito.dart'; import '../src/common.dart'; import '../src/mocks.dart'; -final Platform testPlatform = FakePlatform(environment: {}); +final Platform testPlatform = FakePlatform(environment: const {}); void main() { testWithoutContext('ArtifactUpdater can download a zip archive', () async { @@ -367,6 +367,7 @@ class MockHttpClientResponse extends Mock implements HttpClientResponse { @override Future forEach(void Function(List element) action) async { + action([0]); return; } }