【问题标题】:Difference between throw and $pscmdlet.ThrowTerminatingerror()?throw 和 $pscmdlet.ThrowTerminatingerror() 之间的区别?
【发布时间】:2018-08-18 16:24:50
【问题描述】:

在 PowerShell 中,throw $ErrorMsg$PScmdlet.ThrowTerminatingError($ErrorMsg) 有什么区别?

它们是相同的还是不同的?如果它们不同,哪个更可取?

【问题讨论】:

    标签: powershell exception


    【解决方案1】:

    Throw 创建一个脚本-终止(运行空间-终止)错误,而 $PScmdlet.ThrowTerminatingError() 创建一个语句-终止错误

    注意:这些不是官方术语(文档目前仅在摘要中模糊地引用 terminating 错误,没有范围),但它们对于描述事实上的行为。

    简而言之:默认情况下,

    • 脚本-终止错误会终止整个运行空间,即正在运行的脚本及其所有调用者,不再执行任何语句.

      • 唯一拦截它们的方法是使用try / catch 语句(或者,不太常见的trap 语句)。
    • 语句-终止错误仅终止当前语句(调用$PScmdlet.ThrowTerminatingError()的函数及其所属的语句,通常是一个管道),继续执行 next 语句。

      • 它们也可以被try/catch(或trap)拦截,或者忽略并将$ErrorActionPreference首选项变量设置为SilentlyContinue;相比之下,-ErrorAction 常用参数对它们没有影响。

      • 相反,您可以使用$ErrorActionPreference = 'Stop' 将它们提升为脚本终止错误,尽管文档声称$ErrorActionPreference 仅与 非终止 错误有关,这是第三个错误输入。

    有关详细信息,请参阅this (unofficial) overview of PowerShell's error handling

    至于指导何时使用哪种类型的错误

    • about_Throw 帮助主题中关于何时使用Throw 的指导很少;给出了一个示例用例,其中Throw 用于在没有强制参数的情况下中止函数/脚本,以替代 PowerShell 的默认行为提示

      • 请注意Throw,即抛出一个脚本-终止错误会终止整个运行空间(正在运行的脚本及其任何调用者),除非被捕获。
    • Cmdlet Error Reporting 文章仅讨论 cmdlet-internal 使用何时报告 语句 终止(称为文章中的“终止”)与非终止错误

    鉴于后者,您可能会争辩说,高级函数 - 因为它们就像 cmdlet - 应该至多报告语句 - 终止错误并且Throw脚本-终止错误)应该被限制为脚本,但请注意这与使用Throw 来强制执行强制参数相矛盾。

    也许脚本-终止和语句-终止错误之间的问题区别最终是无意也许最初的意图是只有 script 终止的,这可以解释为什么所有当前文档只在摘要中讨论 terminating 错误,甚至没有提到区别。

    【讨论】:

    • 我更喜欢在 99% 的情况下使用脚本终止错误。这就是异常应该如何工作的方式。不过我意识到,因为它是一个 shell,所以在某些情况下,只写入 stderr 可能是有意义的,主要是在处理多个项目时的管道情况下。但对我来说,这就是“例外”——双关语;)
    • 同意,@marsze。它不会被正式承认,但我仍然怀疑 statement 终止错误是一个意外,正如文档从未区分这两种终止错误子类型的事实所暗示的那样。不管历史是什么,对我来说,消除语句终止错误而只使用脚本终止错误是有道理的——但这不太可能发生。
    猜你喜欢
    • 2020-08-03
    • 2013-10-12
    • 2018-05-30
    • 2016-12-21
    • 2018-02-19
    • 2012-10-01
    • 2010-12-14
    • 1970-01-01
    相关资源
    最近更新 更多