Unverified Commit f766871e authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Forward ProcessException to error handlers (#44783)

parent 01f4f1ac
...@@ -334,17 +334,9 @@ Future<void> buildGradleApp({ ...@@ -334,17 +334,9 @@ Future<void> buildGradleApp({
} }
command.add(assembleTask); command.add(assembleTask);
final Stopwatch sw = Stopwatch()..start();
int exitCode = 1;
GradleHandledError detectedGradleError; GradleHandledError detectedGradleError;
String detectedGradleErrorLine; String detectedGradleErrorLine;
try { String consumeLog(String line) {
exitCode = await processUtils.stream(
command,
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: gradleEnvironment,
mapFunction: (String line) {
// This message was removed from first-party plugins, // This message was removed from first-party plugins,
// but older plugin versions still display this message. // but older plugin versions still display this message.
if (androidXPluginWarningRegex.hasMatch(line)) { if (androidXPluginWarningRegex.hasMatch(line)) {
...@@ -365,8 +357,25 @@ Future<void> buildGradleApp({ ...@@ -365,8 +357,25 @@ Future<void> buildGradleApp({
} }
// Pipe stdout/stderr from Gradle. // Pipe stdout/stderr from Gradle.
return line; return line;
}, }
final Stopwatch sw = Stopwatch()..start();
int exitCode = 1;
try {
exitCode = await processUtils.stream(
command,
workingDirectory: project.android.hostAppGradleRoot.path,
allowReentrantFlutter: true,
environment: gradleEnvironment,
mapFunction: consumeLog,
); );
} on ProcessException catch(exception) {
consumeLog(exception.toString());
// Rethrow the exception if the error isn't handled by any of the
// `localGradleErrors`.
if (detectedGradleError == null) {
rethrow;
}
} finally { } finally {
status.stop(); status.stop();
} }
......
...@@ -85,7 +85,7 @@ final GradleHandledError permissionDeniedErrorHandler = GradleHandledError( ...@@ -85,7 +85,7 @@ final GradleHandledError permissionDeniedErrorHandler = GradleHandledError(
bool usesAndroidX, bool usesAndroidX,
bool shouldBuildPluginAsAar, bool shouldBuildPluginAsAar,
}) async { }) async {
printStatus('$warningMark Gradle does not have permission to execute by your user.', emphasis: true); printStatus('$warningMark Gradle does not have execution permission.', emphasis: true);
printStatus( printStatus(
'You should change the ownership of the project directory to your user, ' 'You should change the ownership of the project directory to your user, '
'or move the project to a directory with execute permissions.', 'or move the project to a directory with execute permissions.',
......
...@@ -231,7 +231,7 @@ Command: /home/android/gradlew assembleRelease ...@@ -231,7 +231,7 @@ Command: /home/android/gradlew assembleRelease
final BufferLogger logger = context.get<Logger>(); final BufferLogger logger = context.get<Logger>();
expect( expect(
logger.statusText, logger.statusText,
contains('Gradle does not have permission to execute by your user.'), contains('Gradle does not have execution permission.'),
); );
expect( expect(
logger.statusText, logger.statusText,
...@@ -399,7 +399,7 @@ Command: /home/android/gradlew assembleRelease ...@@ -399,7 +399,7 @@ Command: /home/android/gradlew assembleRelease
final BufferLogger logger = context.get<Logger>(); final BufferLogger logger = context.get<Logger>();
expect( expect(
logger.statusText, logger.statusText,
contains('Gradle does not have permission to execute by your user.'), contains('Gradle does not have execution permission.'),
); );
expect( expect(
logger.statusText, logger.statusText,
......
...@@ -1266,6 +1266,123 @@ plugin2=${plugin2.path} ...@@ -1266,6 +1266,123 @@ plugin2=${plugin2.path}
Usage: () => mockUsage, 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 { testUsingContext('logs success event after a sucessful retry', () async {
int testFnCalled = 0; int testFnCalled = 0;
when(mockProcessManager.start(any, when(mockProcessManager.start(any,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment