Add more details to ArgumentError if process resolution fails (#59)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5561b7..ec52840 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,9 @@
-#### 4.0.1
+#### 4.1.0
* Fix the signatures of `ProcessManager.run`, `.runSync`, and `.start` to be
consistent with `LocalProcessManager`'s.
+* Added more details to the `ArgumentError` thrown when a command cannot be resolved
+ to an executable.
#### 4.0.0
diff --git a/lib/src/interface/common.dart b/lib/src/interface/common.dart
index a3aed86..2f6a5c9 100644
--- a/lib/src/interface/common.dart
+++ b/lib/src/interface/common.dart
@@ -53,9 +53,9 @@
String? workingDirectory, {
Platform platform = const LocalPlatform(),
FileSystem fs = const LocalFileSystem(),
+ bool errorOnNull = false,
}) {
assert(_osToPathStyle[platform.operatingSystem] == fs.path.style.name);
-
try {
workingDirectory ??= fs.currentDirectory.path;
} on FileSystemException {
@@ -89,6 +89,11 @@
return path;
}
}
+ if (errorOnNull) {
+ throw ArgumentError('Failed to resolve $command to an executable.\n'
+ 'workingDirectory: $workingDirectory, '
+ 'candidates: ${candidates.length}');
+ }
return null;
}
diff --git a/lib/src/interface/local_process_manager.dart b/lib/src/interface/local_process_manager.dart
index a16b753..fe5041c 100644
--- a/lib/src/interface/local_process_manager.dart
+++ b/lib/src/interface/local_process_manager.dart
@@ -105,7 +105,8 @@
@override
bool canRun(covariant String executable, {String? workingDirectory}) =>
- getExecutablePath(executable, workingDirectory) != null;
+ getExecutablePath(executable, workingDirectory, errorOnNull: false) !=
+ null;
@override
bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
@@ -119,7 +120,8 @@
if (runInShell) {
return commandName;
}
- String? exe = getExecutablePath(commandName, workingDirectory);
+ String? exe =
+ getExecutablePath(commandName, workingDirectory, errorOnNull: true);
if (exe == null) {
throw ArgumentError('Cannot find executable for $commandName.');
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 2c6229d..c854b97 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: process
-version: 4.0.1
+version: 4.1.0
description: A pluggable, mockable process invocation abstraction for Dart.
homepage: https://github.com/google/process.dart
diff --git a/test/src/interface/common_test.dart b/test/src/interface/common_test.dart
index 6a3e2df..cbfd180 100644
--- a/test/src/interface/common_test.dart
+++ b/test/src/interface/common_test.dart
@@ -192,6 +192,29 @@
expect(executablePath, isNull);
});
+ test('not found with errorOnNull throws exception with match state', () {
+ String command = 'foo.exe';
+ dynamic error;
+ try {
+ getExecutablePath(
+ command,
+ workingDir.path,
+ platform: platform,
+ fs: fs,
+ errorOnNull: true,
+ );
+ fail('Expected to throw');
+ } catch (err) {
+ error = err;
+ }
+
+ expect(error, isA<ArgumentError>());
+ expect(
+ error.toString(),
+ contains(
+ 'workingDirectory: C:\\.tmp_rand0\\work_dir_rand0, candidates: 2'));
+ });
+
test('when path has spaces', () {
expect(
sanitizeExecutablePath('Program Files\\bla.exe',
@@ -298,6 +321,29 @@
expect(executablePath, isNull);
});
+ test('not found with errorOnNull throws exception with match state', () {
+ String command = 'foo';
+ dynamic error;
+ try {
+ getExecutablePath(
+ command,
+ workingDir.path,
+ platform: platform,
+ fs: fs,
+ errorOnNull: true,
+ );
+ fail('Expected to throw');
+ } catch (err) {
+ error = err;
+ }
+
+ expect(error, isA<ArgumentError>());
+ expect(
+ error.toString(),
+ contains(
+ 'workingDirectory: /.tmp_rand0/work_dir_rand0, candidates: 2'));
+ });
+
test('when path has spaces', () {
expect(
sanitizeExecutablePath('/usr/local/bin/foo bar',