Forward ProcessException to error handlers (#44783)
diff --git a/packages/flutter_tools/test/general.shard/android/gradle_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
index 294716e..8f13098 100644
--- a/packages/flutter_tools/test/general.shard/android/gradle_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
@@ -1266,6 +1266,123 @@
Usage: () => mockUsage,
});
+ testUsingContext('recognizes process exceptions - tool exit', () async {
+ when(mockProcessManager.start(any,
+ workingDirectory: anyNamed('workingDirectory'),
+ environment: anyNamed('environment')))
+ .thenThrow(const ProcessException('', <String>[], 'Some gradle message'));
+
+ fs.directory('android')
+ .childFile('build.gradle')
+ .createSync(recursive: true);
+
+ fs.directory('android')
+ .childFile('gradle.properties')
+ .createSync(recursive: true);
+
+ fs.directory('android')
+ .childDirectory('app')
+ .childFile('build.gradle')
+ ..createSync(recursive: true)
+ ..writeAsStringSync('apply from: irrelevant/flutter.gradle');
+
+ bool handlerCalled = false;
+ await expectLater(() async {
+ await buildGradleApp(
+ project: FlutterProject.current(),
+ androidBuildInfo: const AndroidBuildInfo(
+ BuildInfo(
+ BuildMode.release,
+ null,
+ ),
+ ),
+ target: 'lib/main.dart',
+ isBuildingBundle: false,
+ localGradleErrors: <GradleHandledError>[
+ GradleHandledError(
+ test: (String line) {
+ return line.contains('Some gradle message');
+ },
+ handler: ({
+ String line,
+ FlutterProject project,
+ bool usesAndroidX,
+ bool shouldBuildPluginAsAar,
+ }) async {
+ handlerCalled = true;
+ return GradleBuildStatus.exit;
+ },
+ eventLabel: 'random-event-label',
+ ),
+ ],
+ );
+ },
+ throwsToolExit(
+ message: 'Gradle task assembleRelease failed with exit code 1'
+ ));
+
+ expect(handlerCalled, isTrue);
+
+ verify(mockUsage.sendEvent(
+ any,
+ any,
+ label: 'gradle-random-event-label-failure',
+ parameters: anyNamed('parameters'),
+ )).called(1);
+
+ }, overrides: <Type, Generator>{
+ AndroidSdk: () => mockAndroidSdk,
+ Cache: () => cache,
+ Platform: () => android,
+ FileSystem: () => fs,
+ ProcessManager: () => mockProcessManager,
+ Usage: () => mockUsage,
+ });
+
+ testUsingContext('rethrows unrecognized ProcessException', () async {
+ when(mockProcessManager.start(any,
+ workingDirectory: anyNamed('workingDirectory'),
+ environment: anyNamed('environment')))
+ .thenThrow(const ProcessException('', <String>[], 'Unrecognized'));
+
+ fs.directory('android')
+ .childFile('build.gradle')
+ .createSync(recursive: true);
+
+ fs.directory('android')
+ .childFile('gradle.properties')
+ .createSync(recursive: true);
+
+ fs.directory('android')
+ .childDirectory('app')
+ .childFile('build.gradle')
+ ..createSync(recursive: true)
+ ..writeAsStringSync('apply from: irrelevant/flutter.gradle');
+
+ await expectLater(() async {
+ await buildGradleApp(
+ project: FlutterProject.current(),
+ androidBuildInfo: const AndroidBuildInfo(
+ BuildInfo(
+ BuildMode.release,
+ null,
+ ),
+ ),
+ target: 'lib/main.dart',
+ isBuildingBundle: false,
+ localGradleErrors: const <GradleHandledError>[],
+ );
+ },
+ throwsA(isInstanceOf<ProcessException>()));
+
+ }, overrides: <Type, Generator>{
+ AndroidSdk: () => mockAndroidSdk,
+ Cache: () => cache,
+ Platform: () => android,
+ FileSystem: () => fs,
+ ProcessManager: () => mockProcessManager,
+ });
+
testUsingContext('logs success event after a sucessful retry', () async {
int testFnCalled = 0;
when(mockProcessManager.start(any,