I'm working on a dev tool based on PowerShell. But it always failed in Ubuntu-Latest CI/CD tests. If interested, please check the GitHub Link of Actions
After a day of trying, I found and minimized the process of reproducing the problem.
Consider a directory ${Home}/test/
with a file test_in_method.ps1
and a file test_out_of_method.ps1
as:
${Home}/test/
|----test_in_method.ps1
|----test_out_of_method.ps1
|----(no other items, i.e., no other dirs or files)
The test_in_method.ps1
is as:
# PowerShell 7.3.6 on Windows Or Linux
# test_in_method.ps1
class FormattedFileSystemPath {
FormattedFileSystemPath([string] $Path) {
$link_target = $this.PreProcess()
}
[string] PreProcess(){
Write-Verbose "PWD is:$PWD" -Verbose
return (Get-ChildItem 'usr'| Where-Object Name -eq 'sbin')
}
}
Write-Verbose ([FormattedFileSystemPath]::new('???')) -Verbose
, and the test_out_of_method.ps1
is as:
# PowerShell 7.3.6 on Windows Or Linux
# test_out_of_method.ps1
class FormattedFileSystemPath {
FormattedFileSystemPath([string] $Path) {
Write-Verbose "PWD is:$PWD" -Verbose
$link_target = (Get-ChildItem 'usr'| Where-Object Name -eq 'sbin')
}
}
Write-Verbose ([FormattedFileSystemPath]::new('???')) -Verbose
First, test test_in_method.ps1
as:
pwsh
cd "${Home}/test/"
./ test_in_method.ps1
The output is:
VERBOSE: PWD is:C:\Users\User\test
VERBOSE: FormattedFileSystemPath
Second, test test_out_of_method.ps1
as:
pwsh
cd "${Home}/test/"
./ test_out_of_method.ps1
The out put is:
VERBOSE: PWD is:C:\Users\User\test
Get-ChildItem: C:\Users\User\test\test_out_of_method.ps1:7
Line |
7 | $link_target = (Get-ChildItem 'usr'| Where-Object Name -eq 's …
| ~~~~~~~~~~~~~~~~~~~
| Cannot find path 'C:\Users\User\test\usr' because it does not exist.
VERBOSE: FormattedFileSystemPath
Expected behavior: both test_in_method.ps1
and test_out_of_method.ps1
throw cannot find path
errors
Actual behavior: only test_out_of_method.ps1
throws cannot find path
errors but test_in_method.ps1
does not.
I have tested on my local machines, and both Windows 11 (PowerShellv7.3.6) and WSL2(PowerShellv7.3.5) show the above phenomenon.
Even more strangely, when put into a CI/CD environment, see here, either of the above writes (whether put Get-ChildItem into a class function or a constructor function) can both throw errors as expected.
What's the problem? Why? And how can I deal with it? Why Get-ChildItem
does not throw a cannot find path
error in the class method as expected?
Thanks in advance.
The problem has 2 aspects and can be answered respectively:
Why Get-ChildItem
does not throw a cannot find path
error in a class method as expected? Because:
Why the phenomenon is different the local machines and CI/CD environments?
$ErrorActionPreference
can determine how PowerShell responds to a non-terminating error, an error that doesn't stop the cmdlet processing.$ErrorActionPreference= 'stop'
that is set by many configuration scripts, see an action example, while local machines usually have $ErrorActionPreference = 'Continue'
, which is the default state that displays the error message and continues executing.And how to do it?
I think the best way is as @Santiago Squarzon's comments, adding -ErrorAction Stop
to Get-ChildItem
in class methods. Because it follows the principle of Occam's Razor, with the minimized scope of changes.
Thanks for every above comments and advice.