diff --git a/src/System.Management.Automation/engine/CommandSearcher.cs b/src/System.Management.Automation/engine/CommandSearcher.cs index 002535f2d..3d6918dcf 100644 --- a/src/System.Management.Automation/engine/CommandSearcher.cs +++ b/src/System.Management.Automation/engine/CommandSearcher.cs @@ -460,7 +460,7 @@ namespace System.Management.Automation // Try literal path resolution if it is set to run first if (_commandResolutionOptions.HasFlag(SearchResolutionOptions.ResolveLiteralThenPathPatterns)) { - var path = GetNextLiteralPathThatExists(_commandName, out _); + var path = GetNextLiteralPathThatExistsAndHandleExceptions(_commandName, out _); if (path != null) { @@ -478,7 +478,7 @@ namespace System.Management.Automation if (!_commandResolutionOptions.HasFlag(SearchResolutionOptions.ResolveLiteralThenPathPatterns) && resolvedPaths.Count == 0) { - string path = GetNextLiteralPathThatExists(_commandName, out _); + string path = GetNextLiteralPathThatExistsAndHandleExceptions(_commandName, out _); if (path != null) { @@ -1222,6 +1222,68 @@ namespace System.Management.Automation return result; } + /// + /// Gets the next literal path. + /// Filtering to ones that exist for the filesystem. + /// Handles Exceptions + /// + /// + /// The command to search for. + /// + /// The provider that the command was found in. + /// + /// Full path to the command. + /// + private string GetNextLiteralPathThatExistsAndHandleExceptions(string command, out ProviderInfo provider) + { + try + { + return GetNextLiteralPathThatExists(command, out provider); + } + catch (ItemNotFoundException) + { + CommandDiscovery.discoveryTracer.TraceError( + "The path could not be found: {0}", + _commandName); + } + catch (DriveNotFoundException) + { + // This can be because we think a scope or a url is a drive + // and need to continue searching. + // Although, scope does not work through get-command + CommandDiscovery.discoveryTracer.TraceError( + "A drive could not be found for the path: {0}", + _commandName); + } + catch (ProviderNotFoundException) + { + CommandDiscovery.discoveryTracer.TraceError( + "A provider could not be found for the path: {0}", + _commandName); + } + catch (InvalidOperationException) + { + CommandDiscovery.discoveryTracer.TraceError( + "The path specified a home directory, but the provider home directory was not set. {0}", + _commandName); + } + catch (ProviderInvocationException providerException) + { + CommandDiscovery.discoveryTracer.TraceError( + "The provider associated with the path '{0}' encountered an error: {1}", + _commandName, + providerException.Message); + } + catch (PSNotSupportedException) + { + CommandDiscovery.discoveryTracer.TraceError( + "The provider associated with the path '{0}' does not implement ContainerCmdletProvider", + _commandName); + } + + provider = null; + return null; + } /// /// Gets the next literal path. diff --git a/test/powershell/engine/Basic/CommandDiscovery.Tests.ps1 b/test/powershell/engine/Basic/CommandDiscovery.Tests.ps1 index fa3e957e8..b5f22031e 100644 --- a/test/powershell/engine/Basic/CommandDiscovery.Tests.ps1 +++ b/test/powershell/engine/Basic/CommandDiscovery.Tests.ps1 @@ -207,8 +207,12 @@ Describe "Command Discovery tests" -Tags "CI" { } Context "error cases" { - It 'Get-Command "less `"-PsPage %db?B of %DoesNotExist:`"" should throw Drive not found' { - {Get-Command -Name "less `"-PsPage %db?B of %DoesNotExist:`""} | Should -Throw -ErrorId 'DriveNotFound' -Because "The drive 'DoesNotExist:' should not exist" + It 'Get-Command "less `"-PsPage %db?B of %DoesNotExist:`"" should return nothing' { + Get-Command -Name "less `"-PsPage %db?B of %DoesNotExist:`"" | Should -BeNullOrEmpty + } + + It "Should return command not found for commands in the global scope" { + {Get-Command -Name 'global:help' -ErrorAction Stop} | Should -Throw -ErrorId 'CommandNotFoundException' } } }