From a1852a199337cf2ab945df8810450b44102ed999 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 27 Sep 2019 10:32:38 -0700 Subject: [PATCH] Exit resident web runner on initial compilation failure (#41441) --- .../src/build_runner/resident_web_runner.dart | 4 +- .../lib/src/build_runner/web_fs.dart | 20 ++++++++- .../test/general.shard/web/web_fs_test.dart | 42 ++++++++++++++++++- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart index d73d6170a6b..4eb7ddfa4a7 100644 --- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart @@ -192,9 +192,7 @@ class ResidentWebRunner extends ResidentRunner { _connectionResult = await _webFs.connect(debuggingOptions); unawaited(_connectionResult.debugConnection.onDone.whenComplete(exit)); } - } catch (err, stackTrace) { - printError(err.toString()); - printError(stackTrace.toString()); + } catch (err) { throwToolExit('Failed to build application for the web.'); } finally { buildStatus.stop(); diff --git a/packages/flutter_tools/lib/src/build_runner/web_fs.dart b/packages/flutter_tools/lib/src/build_runner/web_fs.dart index 0fdfc86ddc8..6fcbe4df03d 100644 --- a/packages/flutter_tools/lib/src/build_runner/web_fs.dart +++ b/packages/flutter_tools/lib/src/build_runner/web_fs.dart @@ -135,7 +135,7 @@ class WebFs { _client.startBuild(); await for (BuildResults results in _client.buildResults) { final BuildResult result = results.results.firstWhere((BuildResult result) { - return result.target == 'web'; + return result.target == kBuildTargetName; }); if (result.status == BuildStatus.failed) { return false; @@ -164,6 +164,7 @@ class WebFs { final bool hasWebPlugins = findPlugins(flutterProject) .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey)); // Start the build daemon and run an initial build. + final Completer inititalBuild = Completer(); final BuildDaemonClient client = await buildDaemonCreator .startBuildDaemon(fs.currentDirectory.path, release: buildInfo.isRelease, @@ -178,6 +179,17 @@ class WebFs { return results.results .firstWhere((BuildResult result) => result.target == kBuildTargetName); }); + client.buildResults.listen((BuildResults buildResults) { + final BuildResult result = buildResults.results.firstWhere((BuildResult result) { + return result.target == kBuildTargetName; + }); + if (result.status == BuildStatus.failed) { + inititalBuild.complete(false); + } + if (result.status == BuildStatus.succeeded) { + inititalBuild.complete(true); + } + }); final int daemonAssetPort = buildDaemonCreator.assetServerPort(fs.currentDirectory); // Initialize the asset bundle. @@ -249,13 +261,17 @@ class WebFs { cascade = cascade.add(assetServer.handle); final HttpServer server = await httpMultiServerFactory(hostname ?? _kHostName, hostPort); shelf_io.serveRequests(server, cascade.handler); - return WebFs( + final WebFs webFS = WebFs( client, server, dwds, 'http://$_kHostName:$hostPort/', assetServer, ); + if (!await inititalBuild.future) { + throw Exception('Failed to compile for the web.'); + } + return webFS; } } diff --git a/packages/flutter_tools/test/general.shard/web/web_fs_test.dart b/packages/flutter_tools/test/general.shard/web/web_fs_test.dart index 339b0def18b..475f594070e 100644 --- a/packages/flutter_tools/test/general.shard/web/web_fs_test.dart +++ b/packages/flutter_tools/test/general.shard/web/web_fs_test.dart @@ -4,6 +4,7 @@ import 'package:build_daemon/client.dart'; import 'package:build_daemon/data/build_status.dart'; +import 'package:built_collection/built_collection.dart'; import 'package:dwds/dwds.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/os.dart'; @@ -49,7 +50,18 @@ void main() { return 1234; }); when(mockBuildDaemonClient.buildResults).thenAnswer((Invocation _) { - return const Stream.empty(); + return Stream.fromFuture(Future.value( + BuildResults((BuildResultsBuilder builder) { + builder.results = ListBuilder( + [ + DefaultBuildResult((DefaultBuildResultBuilder builder) { + builder.target = 'web'; + builder.status = BuildStatus.succeeded; + }) + ] + ); + }) + )); }); when(mockBuildDaemonCreator.assetServerPort(any)).thenReturn(4321); testbed = Testbed( @@ -141,6 +153,34 @@ void main() { expect(lastPort, 1234); expect(lastAddress, contains('foo')); })); + + test('Throws exception if build fails', () => testbed.run(() async { + when(mockBuildDaemonClient.buildResults).thenAnswer((Invocation _) { + return Stream.fromFuture(Future.value( + BuildResults((BuildResultsBuilder builder) { + builder.results = ListBuilder( + [ + DefaultBuildResult((DefaultBuildResultBuilder builder) { + builder.target = 'web'; + builder.status = BuildStatus.failed; + }) + ] + ); + }) + )); + }); + final FlutterProject flutterProject = FlutterProject.current(); + + expect(WebFs.start( + skipDwds: false, + target: fs.path.join('lib', 'main.dart'), + buildInfo: BuildInfo.debug, + flutterProject: flutterProject, + initializePlatform: false, + hostname: 'foo', + port: '1234', + ), throwsA(isInstanceOf())); + })); } class MockBuildDaemonCreator extends Mock implements BuildDaemonCreator {}