问题
Experimenting with using classes in powershell, I'm uncertain how to display output. For instance in this code block the write-error does not display the error message:
class Test {
[string] $test
Test ([string] $test) {
$this.test = $test
}
[test] Testfail() {
try {
Get-Childitem F:\ -ErrorAction stop
} catch {
Write-Host "ERROR!!! $this.test"
Exit 1
}
return $this.test + "not an error!"
}
}
In this case it's is obvious that the code runs the catch statement as the powershell window exits but if I comment out the Exit 1 the Write-Host message does not display. Can someone explain how to output the error?
回答1:
Only ever use exit
to exit script files (*.ps1
), not class methods or functions.
Calling exit
from a class method or function will instantly exit the PowerShell process as a whole.
To report an error from a class method, use a terminating error, which is what -ErrorAction Stop
or the Throw
statement generate.
That is, simply use Get-Childitem F:\ -ErrorAction stop
without try
/ catch
, which causes a (runspace-)terminating error that the caller will have to catch.
If, by contrast, you simply want to issue an error message in your method, without affecting the flow of execution, note that you cannot use Write-Error
from a class method; however, you can use Write-Warning
(Write-Host
works too, but its use is not advisable).
- Caveat: You cannot blindly use
return
to exit a method, unless it is[void]
-typed. You are forced to return an instance of the declared return type, and whilereturn $null
works well to signify "no return value" for reference types, usingreturn $null
with a value type such as[int]
or[datetime]
either converts the$null
to that type (resulting in0
for return type[int]
) or breaks (for return type[datetime]
, because$null
cannot be meaningfully converted to that type).
In short: Class methods in PowerShell behave differently from other PowerShell code:
To write to the success output stream, you must use the
return
statement; implicit output isn't supported.To report an error, you must generate a terminating error, either via common parameter
-ErrorAction Stop
, aThrow
statement, or by calling a .NET method that generates an exception; non-terminating errors and attempts to write to the error stream directly withWrite-Error
are quietly ignored.All other outputs streams (see about_redirection), however, are passed through.
This perhaps surprising discrepancy is discussed in this GitHub issue and a request to clarify the behavior in the documentation can be found in this GitHub docs issue.
来源:https://stackoverflow.com/questions/59241859/output-for-try-catch-in-powershell-classes