Verbose process exceptions (#61552)
This commit is contained in:
parent
9ef8192760
commit
f796e047fd
@ -226,6 +226,7 @@ class _PosixUtils extends OperatingSystemUtils {
|
||||
_processUtils.runSync(
|
||||
<String>['unzip', '-o', '-q', file.path, '-d', targetDirectory.path],
|
||||
throwOnError: true,
|
||||
verboseExceptions: true,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -231,6 +231,7 @@ abstract class ProcessUtils {
|
||||
RunResult runSync(
|
||||
List<String> cmd, {
|
||||
bool throwOnError = false,
|
||||
bool verboseExceptions = false,
|
||||
RunResultChecker allowedFailures,
|
||||
bool hideStdout = false,
|
||||
String workingDirectory,
|
||||
@ -408,6 +409,7 @@ class _DefaultProcessUtils implements ProcessUtils {
|
||||
RunResult runSync(
|
||||
List<String> cmd, {
|
||||
bool throwOnError = false,
|
||||
bool verboseExceptions = false,
|
||||
RunResultChecker allowedFailures,
|
||||
bool hideStdout = false,
|
||||
String workingDirectory,
|
||||
@ -449,7 +451,12 @@ class _DefaultProcessUtils implements ProcessUtils {
|
||||
}
|
||||
|
||||
if (failedExitCode && throwOnError) {
|
||||
runResult.throwException('The command failed');
|
||||
String message = 'The command failed';
|
||||
if (verboseExceptions) {
|
||||
message = 'The command failed\nStdout:\n${runResult.stdout}\n'
|
||||
'Stderr:\n${runResult.stderr}';
|
||||
}
|
||||
runResult.throwException(message);
|
||||
}
|
||||
|
||||
return runResult;
|
||||
|
@ -89,6 +89,31 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('If unzip fails, include stderr in exception text', () {
|
||||
const String exceptionMessage = 'Something really bad happened.';
|
||||
when(mockProcessManager.runSync(
|
||||
<String>['unzip', '-o', '-q', null, '-d', null],
|
||||
)).thenReturn(ProcessResult(0, 1, '', exceptionMessage));
|
||||
final MockFileSystem fileSystem = MockFileSystem();
|
||||
final MockFile mockFile = MockFile();
|
||||
final MockDirectory mockDirectory = MockDirectory();
|
||||
when(fileSystem.file(any)).thenReturn(mockFile);
|
||||
when(mockFile.readAsBytesSync()).thenThrow(
|
||||
const FileSystemException(exceptionMessage),
|
||||
);
|
||||
final OperatingSystemUtils osUtils = OperatingSystemUtils(
|
||||
fileSystem: fileSystem,
|
||||
logger: BufferLogger.test(),
|
||||
platform: FakePlatform(operatingSystem: 'linux'),
|
||||
processManager: mockProcessManager,
|
||||
);
|
||||
|
||||
expect(
|
||||
() => osUtils.unzip(mockFile, mockDirectory),
|
||||
throwsProcessException(message: exceptionMessage),
|
||||
);
|
||||
});
|
||||
|
||||
group('gzip on Windows:', () {
|
||||
testWithoutContext('verifyGzip returns false on a FileSystemException', () {
|
||||
final MockFileSystem fileSystem = MockFileSystem();
|
||||
@ -148,5 +173,6 @@ void main() {
|
||||
}
|
||||
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockDirectory extends Mock implements Directory {}
|
||||
class MockFileSystem extends Mock implements FileSystem {}
|
||||
class MockFile extends Mock implements File {}
|
||||
|
@ -286,12 +286,33 @@ void main() {
|
||||
expect(processUtils.runSync(<String>['boohoo']).exitCode, 1);
|
||||
});
|
||||
|
||||
testWithoutContext(' throws on failure with throwOnError', () async {
|
||||
testWithoutContext('throws on failure with throwOnError', () async {
|
||||
const String stderr = 'Something went wrong.';
|
||||
when(mockProcessManager.runSync(<String>['kaboom'])).thenReturn(
|
||||
ProcessResult(0, 1, '', '')
|
||||
ProcessResult(0, 1, '', stderr),
|
||||
);
|
||||
try {
|
||||
processUtils.runSync(<String>['kaboom'], throwOnError: true);
|
||||
fail('ProcessException expected.');
|
||||
} on ProcessException catch (e) {
|
||||
expect(e, isA<ProcessException>());
|
||||
expect(e.message.contains(stderr), false);
|
||||
}
|
||||
});
|
||||
|
||||
testWithoutContext('throws with stderr in exception on failure with verboseExceptions', () async {
|
||||
const String stderr = 'Something went wrong.';
|
||||
when(mockProcessManager.runSync(<String>['verybad'])).thenReturn(
|
||||
ProcessResult(0, 1, '', stderr),
|
||||
);
|
||||
expect(
|
||||
() => processUtils.runSync(
|
||||
<String>['verybad'],
|
||||
throwOnError: true,
|
||||
verboseExceptions: true,
|
||||
),
|
||||
throwsProcessException(message: stderr),
|
||||
);
|
||||
expect(() => processUtils.runSync(<String>['kaboom'], throwOnError: true),
|
||||
throwsA(isA<ProcessException>()));
|
||||
});
|
||||
|
||||
testWithoutContext(' does not throw on allowed Failures', () async {
|
||||
|
@ -13,7 +13,7 @@ import 'package:vm_service/vm_service.dart' as vm_service;
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/context.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/process.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/commands/create.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command.dart';
|
||||
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
|
||||
@ -106,15 +106,17 @@ Matcher throwsToolExit({ int exitCode, Pattern message }) {
|
||||
/// Matcher for [ToolExit]s.
|
||||
final test_package.TypeMatcher<ToolExit> isToolExit = isA<ToolExit>();
|
||||
|
||||
/// Matcher for functions that throw [ProcessExit].
|
||||
Matcher throwsProcessExit([ dynamic exitCode ]) {
|
||||
return exitCode == null
|
||||
? throwsA(isProcessExit)
|
||||
: throwsA(allOf(isProcessExit, (ProcessExit e) => e.exitCode == exitCode));
|
||||
/// Matcher for functions that throw [ProcessException].
|
||||
Matcher throwsProcessException({ Pattern message }) {
|
||||
Matcher matcher = isProcessException;
|
||||
if (message != null) {
|
||||
matcher = allOf(matcher, (ProcessException e) => e.message?.contains(message));
|
||||
}
|
||||
return throwsA(matcher);
|
||||
}
|
||||
|
||||
/// Matcher for [ProcessExit]s.
|
||||
final test_package.TypeMatcher<ProcessExit> isProcessExit = isA<ProcessExit>();
|
||||
/// Matcher for [ProcessException]s.
|
||||
final test_package.TypeMatcher<ProcessException> isProcessException = isA<ProcessException>();
|
||||
|
||||
/// Creates a flutter project in the [temp] directory using the
|
||||
/// [arguments] list if specified, or `--no-pub` if not.
|
||||
|
Loading…
x
Reference in New Issue
Block a user