From c81f4c71a2fa390f4ada8a404cae3d7bb8100cac Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Mon, 8 Oct 2018 19:11:31 -0700 Subject: [PATCH] Have runAsyncChecked throw a ProcessException instead of a String. (#22710) --- .../flutter_tools/lib/src/base/process.dart | 6 ++-- .../flutter_tools/lib/src/ios/simulators.dart | 30 ++++++++++++++++--- .../flutter_tools/test/base/process_test.dart | 18 +++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart index c612e453587..5632752b942 100644 --- a/packages/flutter_tools/lib/src/base/process.dart +++ b/packages/flutter_tools/lib/src/base/process.dart @@ -247,8 +247,10 @@ Future runCheckedAsync(List cmd, { allowReentrantFlutter: allowReentrantFlutter, environment: environment, ); - if (result.exitCode != 0) - throw 'Exit code ${result.exitCode} from: ${cmd.join(' ')}:\n$result'; + if (result.exitCode != 0) { + throw ProcessException(cmd[0], cmd.sublist(1), + 'Process "${cmd[0]}" exited abnormally:\n$result', result.exitCode); + } return result; } diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 587d6c6a324..207e822c379 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -120,22 +120,44 @@ class SimControl { } Future install(String deviceId, String appPath) { - return runCheckedAsync([_xcrunPath, 'simctl', 'install', deviceId, appPath]); + Future result; + try { + result = runCheckedAsync([_xcrunPath, 'simctl', 'install', deviceId, appPath]); + } on ProcessException catch (exception) { + throwToolExit('Unable to install $appPath on $deviceId:\n$exception'); + } + return result; } Future uninstall(String deviceId, String appId) { - return runCheckedAsync([_xcrunPath, 'simctl', 'uninstall', deviceId, appId]); + Future result; + try { + result = runCheckedAsync([_xcrunPath, 'simctl', 'uninstall', deviceId, appId]); + } on ProcessException catch (exception) { + throwToolExit('Unable to uninstall $appId from $deviceId:\n$exception'); + } + return result; } Future launch(String deviceId, String appIdentifier, [List launchArgs]) { final List args = [_xcrunPath, 'simctl', 'launch', deviceId, appIdentifier]; if (launchArgs != null) args.addAll(launchArgs); - return runCheckedAsync(args); + Future result; + try { + result = runCheckedAsync(args); + } on ProcessException catch (exception) { + throwToolExit('Unable to launch $appIdentifier on $deviceId:\n$exception'); + } + return result; } Future takeScreenshot(String deviceId, String outputPath) async { - await runCheckedAsync([_xcrunPath, 'simctl', 'io', deviceId, 'screenshot', outputPath]); + try { + await runCheckedAsync([_xcrunPath, 'simctl', 'io', deviceId, 'screenshot', outputPath]); + } on ProcessException catch (exception) { + throwToolExit('Unable to take screenshot of $deviceId:\n$exception'); + } } } diff --git a/packages/flutter_tools/test/base/process_test.dart b/packages/flutter_tools/test/base/process_test.dart index 5f4aa4d54d9..1281a92f371 100644 --- a/packages/flutter_tools/test/base/process_test.dart +++ b/packages/flutter_tools/test/base/process_test.dart @@ -2,12 +2,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/process.dart'; +import 'package:mockito/mockito.dart'; +import 'package:process/process.dart'; import '../src/common.dart'; import '../src/context.dart'; void main() { + group('process exceptions', () { + ProcessManager mockProcessManager; + + setUp(() { + mockProcessManager = MockProcessManager(); + }); + + testUsingContext('runCheckedAsync exceptions should be ProcessException objects', () async { + when(mockProcessManager.run(['false'])) + .thenAnswer((Invocation invocation) => Future.value(ProcessResult(0, 1, '', ''))); + expect(() async => await runCheckedAsync(['false']), throwsA(isInstanceOf())); + }, overrides: {ProcessManager: () => mockProcessManager}); + }); group('shutdownHooks', () { testUsingContext('runInExpectedOrder', () async { int i = 1; @@ -41,3 +57,5 @@ void main() { }); }); } + +class MockProcessManager extends Mock implements ProcessManager {}