在PowerShell中,throw $ErrorMsg
和$PScmdlet.ThrowTerminatingError($ErrorMsg)
有什么区别?
它们是相同的还是不同的?如果它们是不同的,哪一个更好?
在PowerShell中,throw $ErrorMsg
和$PScmdlet.ThrowTerminatingError($ErrorMsg)
有什么区别?
它们是相同的还是不同的?如果它们是不同的,哪一个更好?
Throw
会创建一个脚本(或者runspace)终止错误,而$PScmdlet.ThrowTerminatingError()
会创建一个语句终止错误。
注意:虽然这些不是官方术语(文档目前只含糊地提到了抽象的“终止”错误,没有范围),但它们有助于描述实际行为。
简而言之:
一个脚本终止错误默认情况下会终止整个runspace,也就是运行中的脚本和所有调用者,并且没有进一步的语句会执行;换句话说:除非这样的错误被捕获或者被抑制,否则它是致命的。
可以通过将$ErrorActionPreference
偏好变量设置为'SilentlyContinue'
或者(仅适用于PowerShell (Core) 7+)的'Ignore'
来抑制它们。
一个语句终止错误仅会终止当前语句(调用$PScmdlet.ThrowTerminatingError()
并且它是一个部分的语句,通常是一个管道),默认情况下执行将继续执行下一条语句.
它们可以以与脚本终止错误相同的方式被捕获或抑制,但请注意,通用的-ErrorAction
参数对它们没有影响.
相反,您可以使用$ErrorActionPreference='Stop'
将它们提升为脚本终止错误,尽管文档声称$ErrorActionPreference
仅适用于非终止错误,即第三种错误类型(独占应用于-ErrorAction
参数).
有关更多信息,请参见此(非官方)PowerShell错误处理概述.
至于何时使用哪种类型的错误的指导:
在about_Throw
帮助主题中,很少有关于何时使用Throw
的指导;给出了一个示例用例,其中Throw
用于在缺少强制参数时中止函数/脚本,作为替代PowerShell默认行为的提示。
Cmdlet错误报告文章仅讨论与报告语句-终止(在该文章中称为“终止”)和非终止错误有关的命令-内部使用。
鉴于后者,您可以认为高级功能——因为它们像cmdlet一样——应该最多报告语句-终止错误,并且Throw
(脚本-终止错误)应该限于脚本,但请注意,这与使用Throw
强制实施强制参数的用法相矛盾。
也许在“脚本终止”和“语句终止”错误之间的棘手区别最终是无意的,而也许最初的意图只是有脚本终止错误,这就解释了为什么所有当前文档只谈论关于终止错误的概述,甚至没有提到这种区别。