Skip to content

Commit da30f45

Browse files
author
annavied_microsoft
committed
Local repository network connection failure should not fail silently
1 parent 80d1ef0 commit da30f45

3 files changed

Lines changed: 160 additions & 9 deletions

File tree

src/code/LocalServerApiCalls.cs

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,24 @@ private FindResults FindNameHelper(string packageName, string[] tags, bool inclu
263263
string regexPattern = $"{packageName}" + @"(\.\d+){1,3}(?:[a-zA-Z0-9-.]+|.\d)?\.nupkg";
264264
_cmdletPassedIn.WriteDebug($"package file name pattern to be searched for is: {regexPattern}");
265265

266-
foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath))
266+
string[] foundFiles = Utils.EmptyStrArray;
267+
try
268+
{
269+
foundFiles = Directory.GetFiles(Repository.Uri.LocalPath);
270+
}
271+
catch (Exception e)
272+
{
273+
_cmdletPassedIn.WriteWarning($"Unable to resolve repository source '{Repository.Uri.LocalPath}' due to exception: {e.Message}");
274+
errRecord = new ErrorRecord(
275+
exception: e,
276+
"FileAccessFailure",
277+
ErrorCategory.ReadError,
278+
this);
279+
280+
return findResponse;
281+
}
282+
283+
foreach (string path in foundFiles)
267284
{
268285
string packageFullName = Path.GetFileName(path);
269286
bool isMatch = Regex.IsMatch(packageFullName, regexPattern, RegexOptions.IgnoreCase);
@@ -333,7 +350,12 @@ private FindResults FindNameGlobbingHelper(string packageName, string[] tags, bo
333350
List<Hashtable> pkgsFound = new List<Hashtable>();
334351
errRecord = null;
335352

336-
Hashtable pkgVersionsFound = GetMatchingFilesGivenNamePattern(packageNameWithWildcard: packageName, includePrerelease: includePrerelease);
353+
Hashtable pkgVersionsFound = GetMatchingFilesGivenNamePattern(packageNameWithWildcard: packageName, includePrerelease: includePrerelease, out errRecord);
354+
if (errRecord != null)
355+
{
356+
// ErrorRecord errRecord is only set if directory access to retrieve files failed (i.e network error when accessing file share, incorrect directory path, etc), not if desired files within directory are not found since this is a wildcard scenario.
357+
return findResponse;
358+
}
337359

338360
List<string> pkgNamesList = pkgVersionsFound.Keys.Cast<string>().ToList();
339361
foreach(string pkgFound in pkgNamesList)
@@ -382,7 +404,24 @@ private FindResults FindVersionHelper(string packageName, string version, string
382404
string pkgPath = String.Empty;
383405
string actualPkgName = String.Empty;
384406

385-
foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath))
407+
string[] foundFiles = Utils.EmptyStrArray;
408+
try
409+
{
410+
foundFiles = Directory.GetFiles(Repository.Uri.LocalPath);
411+
}
412+
catch (Exception e)
413+
{
414+
_cmdletPassedIn.WriteWarning($"Unable to resolve repository source '{Repository.Uri.LocalPath}' due to exception: {e.Message}");
415+
errRecord = new ErrorRecord(
416+
exception: e,
417+
"FileAccessFailure",
418+
ErrorCategory.ReadError,
419+
this);
420+
421+
return findResponse;
422+
}
423+
424+
foreach (string path in foundFiles)
386425
{
387426
string packageFullName = Path.GetFileName(path);
388427
bool isMatch = Regex.IsMatch(packageFullName, regexPattern, RegexOptions.IgnoreCase);
@@ -450,7 +489,12 @@ private FindResults FindTagsHelper(string[] tags, bool includePrerelease, out Er
450489
List<Hashtable> pkgsFound = new List<Hashtable>();
451490
errRecord = null;
452491

453-
Hashtable pkgVersionsFound = GetMatchingFilesGivenNamePattern(packageNameWithWildcard: String.Empty, includePrerelease: includePrerelease);
492+
Hashtable pkgVersionsFound = GetMatchingFilesGivenNamePattern(packageNameWithWildcard: String.Empty, includePrerelease: includePrerelease, errRecord: out errRecord);
493+
if (errRecord != null)
494+
{
495+
// ErrorRecord errRecord is only set if directory access to retrieve files failed (i.e network error when accessing file share, incorrect directory path, etc), not if desired files within directory are not found since this is a wildcard scenario.
496+
return findResponse;
497+
}
454498

455499
List<string> pkgNamesList = pkgVersionsFound.Keys.Cast<string>().ToList();
456500
foreach(string pkgFound in pkgNamesList)
@@ -496,7 +540,24 @@ private Stream InstallName(string packageName, bool includePrerelease, out Error
496540
NuGetVersion latestVersion = new NuGetVersion("0.0.0.0");
497541
String latestVersionPath = String.Empty;
498542

499-
foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath))
543+
string[] foundFiles = Utils.EmptyStrArray;
544+
try
545+
{
546+
foundFiles = Directory.GetFiles(Repository.Uri.LocalPath);
547+
}
548+
catch (Exception e)
549+
{
550+
_cmdletPassedIn.WriteWarning($"Unable to resolve repository source '{Repository.Uri.LocalPath}' due to exception: {e.Message}");
551+
errRecord = new ErrorRecord(
552+
exception: e,
553+
"FileAccessFailure",
554+
ErrorCategory.ReadError,
555+
this);
556+
557+
return fs;
558+
}
559+
560+
foreach (string path in foundFiles)
500561
{
501562
string packageFullName = Path.GetFileName(path);
502563

@@ -581,7 +642,24 @@ private Stream InstallVersion(string packageName, string version, out ErrorRecor
581642
WildcardPattern pkgNamePattern = new WildcardPattern($"{packageName}.{version}.nupkg*", WildcardOptions.IgnoreCase);
582643
String pkgVersionPath = String.Empty;
583644

584-
foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath))
645+
string[] foundFiles = Utils.EmptyStrArray;
646+
try
647+
{
648+
foundFiles = Directory.GetFiles(Repository.Uri.LocalPath);
649+
}
650+
catch (Exception e)
651+
{
652+
_cmdletPassedIn.WriteWarning($"Unable to resolve repository source '{Repository.Uri.LocalPath}' due to exception: {e.Message}");
653+
errRecord = new ErrorRecord(
654+
exception: e,
655+
"FileAccessFailure",
656+
ErrorCategory.ReadError,
657+
this);
658+
659+
return fs;
660+
}
661+
662+
foreach (string path in foundFiles)
585663
{
586664
string packageFullName = Path.GetFileName(path);
587665

@@ -778,7 +856,24 @@ private Hashtable GetMatchingFilesGivenSpecificName(string packageName, bool inc
778856
Hashtable pkgVersionsFound = new Hashtable(StringComparer.OrdinalIgnoreCase);
779857
errRecord = null;
780858

781-
foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath))
859+
string[] foundFiles = Utils.EmptyStrArray;
860+
try
861+
{
862+
foundFiles = Directory.GetFiles(Repository.Uri.LocalPath);
863+
}
864+
catch (Exception e)
865+
{
866+
_cmdletPassedIn.WriteWarning($"Unable to resolve repository source '{Repository.Uri.LocalPath}' due to exception: {e.Message}");
867+
errRecord = new ErrorRecord(
868+
exception: e,
869+
"FileAccessFailure",
870+
ErrorCategory.ReadError,
871+
this);
872+
873+
return pkgVersionsFound;
874+
}
875+
876+
foreach (string path in foundFiles)
782877
{
783878
string packageFullName = Path.GetFileName(path);
784879

@@ -809,9 +904,10 @@ private Hashtable GetMatchingFilesGivenSpecificName(string packageName, bool inc
809904
/// hashtable with those that match the name wildcard pattern and prerelease requirements provided.
810905
/// This helper method is called for FindAll(), FindTags(), FindNameGlobbing() scenarios.
811906
/// </summary>
812-
private Hashtable GetMatchingFilesGivenNamePattern(string packageNameWithWildcard, bool includePrerelease)
907+
private Hashtable GetMatchingFilesGivenNamePattern(string packageNameWithWildcard, bool includePrerelease, out ErrorRecord errRecord)
813908
{
814909
_cmdletPassedIn.WriteDebug("In LocalServerApiCalls::GetMatchingFilesGivenNamePattern()");
910+
errRecord = null;
815911
bool isNameFilteringRequired = !String.IsNullOrEmpty(packageNameWithWildcard);
816912

817913
// wildcard name possibilities: power*, *get, power*get
@@ -820,7 +916,24 @@ private Hashtable GetMatchingFilesGivenNamePattern(string packageNameWithWildcar
820916
Regex rx = new Regex(@"\.\d+\.", RegexOptions.Compiled | RegexOptions.IgnoreCase);
821917
Hashtable pkgVersionsFound = new Hashtable(StringComparer.OrdinalIgnoreCase);
822918

823-
foreach (string path in Directory.GetFiles(Repository.Uri.LocalPath))
919+
string[] foundFiles = Utils.EmptyStrArray;
920+
try
921+
{
922+
foundFiles = Directory.GetFiles(Repository.Uri.LocalPath);
923+
}
924+
catch (Exception e)
925+
{
926+
_cmdletPassedIn.WriteWarning($"Unable to resolve repository source '{Repository.Uri.LocalPath}' due to exception: {e.Message}");
927+
errRecord = new ErrorRecord(
928+
exception: e,
929+
"FileAccessFailure",
930+
ErrorCategory.ReadError,
931+
this);
932+
933+
return pkgVersionsFound;
934+
}
935+
936+
foreach (string path in foundFiles)
824937
{
825938
string packageFullName = Path.GetFileName(path);
826939
MatchCollection matches = rx.Matches(packageFullName);

test/FindPSResourceTests/FindPSResourceLocal.Tests.ps1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' {
1212
BeforeAll{
1313
$localRepo = "psgettestlocal"
1414
$localUNCRepo = 'psgettestlocal3'
15+
$localPrivateRepo = "psgettestlocal5"
1516
$testModuleName = "test_local_mod"
1617
$testModuleName2 = "test_local_mod2"
1718
$testModuleName3 = "Test_Local_Mod3"
@@ -347,4 +348,22 @@ Describe 'Test Find-PSResource for local repositories' -tags 'CI' {
347348
$res = Find-PSResource -Name 'Az.KeyVault' -Repository $localRepo
348349
$res.Version | Should -Be "6.3.1"
349350
}
351+
352+
It "Find should not silently fail if network connection to local private repository cannot be established and remainder repositories should be searched" {
353+
$privateRepo = Get-PSResourceRepository $localPrivateRepo
354+
$res = Find-PSResource -Name $testModuleName -WarningVariable WarningVar -WarningAction SilentlyContinue
355+
$WarningVar | Should -Not -BeNullOrEmpty
356+
$WarningVar[0] | Should -Match "$($privateRepo.Uri.LocalPath)"
357+
$res.Name | Should -Contain $testModuleName
358+
$res.Version | Should -Be "1.0.0"
359+
}
360+
361+
It "Find should not silently fail if network connection to local private repository cannot be established and package version was provided and remainder repositories should be searched" {
362+
$privateRepo = Get-PSResourceRepository $localPrivateRepo
363+
$res = Find-PSResource -Name $testModuleName -Version "1.0.0" -WarningVariable WarningVar -WarningAction SilentlyContinue
364+
$WarningVar | Should -Not -BeNullOrEmpty
365+
$WarningVar[0] | Should -Match "$($privateRepo.Uri.LocalPath)"
366+
$res.Name | Should -Contain $testModuleName
367+
$res.Version | Should -Be "1.0.0"
368+
}
350369
}

test/InstallPSResourceTests/InstallPSResourceLocal.Tests.ps1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Describe 'Test Install-PSResource for local repositories' -tags 'CI' {
1616
BeforeAll {
1717
$localRepo = "psgettestlocal"
1818
$localUNCRepo = "psgettestlocal3"
19+
$localPrivateRepo = "psgettestlocal5"
1920
$localNupkgRepo = "localNupkgRepo"
2021
$testModuleName = "test_local_mod"
2122
$testModuleName2 = "test_local_mod2"
@@ -296,4 +297,22 @@ Describe 'Test Install-PSResource for local repositories' -tags 'CI' {
296297
$pkg.Name | Should -Be $nupkgName
297298
$pkg.Version | Should -Be $nupkgVersion
298299
}
300+
301+
It "Install should not silently fail if network connection to local private repository cannot be established and remainder repositories should be searched" {
302+
$privateRepo = Get-PSResourceRepository $localPrivateRepo
303+
$res = Install-PSResource -Name $testModuleName -TrustRepository -PassThru -WarningVariable WarningVar -WarningAction SilentlyContinue
304+
$WarningVar | Should -Not -BeNullOrEmpty
305+
$WarningVar[0] | Should -Match "$($privateRepo.Uri.LocalPath)"
306+
$res.Name | Should -Contain $testModuleName
307+
$res.Version | Should -Be "1.0.0"
308+
}
309+
310+
It "Install should not silently fail if network connection to local private repository cannot be established and package version was provided and remainder repositories should be searched" {
311+
$privateRepo = Get-PSResourceRepository $localPrivateRepo
312+
$res = Install-PSResource -Name $testModuleName -Version "1.0.0" -TrustRepository -PassThru -WarningVariable WarningVar -WarningAction SilentlyContinue
313+
$WarningVar | Should -Not -BeNullOrEmpty
314+
$WarningVar[0] | Should -Match "$($privateRepo.Uri.LocalPath)"
315+
$res.Name | Should -Contain $testModuleName
316+
$res.Version | Should -Be "1.0.0"
317+
}
299318
}

0 commit comments

Comments
 (0)