且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在Powershell类中进行try/catch的输出

更新时间:2023-02-06 12:05:58

仅使用 exit 退出 script文件( *.ps1 ),而不是类方法函数.

从类方法或函数中调用 exit 会立即整体退出PowerShell进程 .

要报告类方法中的错误,请使用终止错误 ,即 -ErrorAction Stop Throw语句生成.

也就是说,只需使用 Get-Childitem F:\ -ErrorAction stop 而无需 try / catch 导致调用方必须捕获的(线程终止)错误.

相反,如果您只是想在方法中发出错误 message 而又不影响执行流程,请注意,您不能使用 Write-错误来自类方法;但是,您可以使用 Write-Warning ( Write-Host 也可以,但是不建议使用).

  • 注意事项:您不能盲目地使用 return 退出方法,除非它是 [void] -输入.您必须返回声明的返回类型的实例,而 return $ null 可以很好地表示无返回值".对于 reference 类型,请使用具有 value 类型的 return $ null ,例如 [int] [datetime] 或将 $ null 转换为该类型(返回类型为 [int] 的结果为 0 )或中断(对于返回类型 [datetime] ,因为 $ null 无法有意义地转换为该类型).

简而言之: PowerShell中的类方法的行为不同于其他PowerShell代码:

  • 要写入成功输出流,必须使用 return 语句;不支持隐式输出.

  • 要报告错误,必须通过通用参数 -ErrorAction Stop Throw 语句生成终止错误.,或调用产生异常的.NET方法;非终止错误,并尝试直接通过 Write-Error 写入错误流,而忽略.

  • 所有其他输出流(请参阅此GitHub问题中讨论了这个也许令人惊讶的差异,并要求澄清可以在此GitHub文档版本中找到文档中的行为..>

    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?

    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 (thread-)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 while return $null works well to signify "no return value" for reference types, using return $null with a value type such as [int] or [datetime] either converts the $null to that type (resulting in 0 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, a Throw statement, or by calling a .NET method that generates an exception; non-terminating errors and attempts to write to the error stream directly with Write-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.