【问题标题】:powershell call to extended property fails silently ( Added via Update-TypeData )对扩展属性的 powershell 调用静默失败(通过 Update-TypeData 添加)
【发布时间】:2013-11-03 23:43:27
【问题描述】:

我的问题是:

  • 为什么这个错误没有被抛出到代码中?
  • 如何让错误被抛出到代码中?
  • 我在哪里/我怎么能自己解决这个问题? / 这个“特性”的文档在哪里?

    Function demo_problem
    {
        describe_global_error_variable
        $ret_value = "be loud please".extended_property
        write-host "returned a value=[$ret_value]."
        describe_global_error_variable
    }
    
    
    Function describe_global_error_variable
    {
        $cnt = $Error.Count
        write-host "`$Error .Count=[$($cnt)]." 
        $i=0
        while ($i -lt $cnt) {
            write-host "`$Error[$i].Exception.Message=[$($Error[$i].Exception.Message)]"
            $i += 1
            }
    }
    
    $script_block_throws = { 
            write-host "at beginning of script_block for script_block_throws.  `$this=[$this]."
            1/0
            return $true
            write-host "at end of script_block for script_block_throws.  `$this=[$this]."
        }
    
    $script_block_try_catch_throw = { 
            write-host "at beginning of script_block for script_block_try_catch_throw.  `$this=[$this]."
            try
            {
                1/0
                return $true
            }
            catch [Exception]{
                write-host "script_block_try_catch_throw caught an exception"
                throw "caught an exception" 
            }
            return $false
            write-host "at end of script_block for script_block_try_catch_throw.  `$this=[$this]."
        }
    
    try {
        Update-TypeData -Value:$script_block_throws -TypeName:System.String -MemberName:extended_property -Force -MemberType:ScriptProperty 
        demo_problem
        Update-TypeData -Value:$script_block_try_catch_throw -TypeName:System.String -MemberName:extended_property -Force -MemberType:ScriptProperty 
        demo_problem
    }
    catch [Exception]{
        write-host "exception got thrown out of the script block...."   
    }
    
    <#
    PS C:\ .\powershell_call_to_extended_property_fails_silently.ps1
    $Error .Count=[0]. \
    at beginning of script_block for script_block_throws.  $this=[be loud please].
    returned a value=[].
    $Error .Count=[1]. \
    $Error[0].Exception.Message=[Attempted to divide by zero.]
    $Error .Count=[1]. \
    $Error[0].Exception.Message=[Attempted to divide by zero.]
    at beginning of script_block for script_block_try_catch_throw.  $this=[be loud please].
    script_block_try_catch_throw caught an exception
    returned a value=[].
    $Error .Count=[3]. \
    $Error[0].Exception.Message=[caught an exception]
    $Error[1].Exception.Message=[Attempted to divide by zero.]
    $Error[2].Exception.Message=[Attempted to divide by zero.]
    #>
    

【问题讨论】:

    标签: exception powershell extension-methods swallowed-exceptions


    【解决方案1】:

    PowerShell 团队告诉我,属性的异常总是被屏蔽,因为在格式化和输出过程中会大量使用属性。 ScriptMethod 不会屏蔽异常。虽然从调试的角度来看这是不幸的,但通常属性不应该做的不仅仅是获取和设置状态。我还要补充一点,.NET 开发人员不希望抛出属性。

    如果您不喜欢这种行为,请随时在http://connect.microsoft.com 网站上提交问题。我知道至少有一个 PowerShell 开发人员不喜欢异常是 always 隐藏的,即即使在格式化操作之外。对此有一些客户意见可以帮助开发人员提出改变行为的理由 - 至少在严格模式下是这样。

    【讨论】:

    • @keith-hill Properties 做更多,例如看看 WPF。获取和设置状态只是它的核心。 Powershell 实际上与 WPF 非常相似,因为它们的视觉表现也具有不可替代的属性。除了所有例外情况,即使是像惰性评估这样简单和标准的场景,对于许多任务来说也可能是不可能/不负责任的。您确定至少没有一种异常类型可以通过吗?可能没有另一个 .NET 团队有能力将整个 IL 功能的所有异常都静音。
    • 我认为这是最烦人的,因为异常只能在运行时生成,因此,如果有人想在能够分配值之前进行类型检查,那么这里就是这样做的地方。
    【解决方案2】:

    我真的认为这是某种范围问题或错误。我能够很容易地复制它。我能够解决问题的唯一方法是通过一种变通方法,如下所示:

    Update-TypeData -Value:$script_block_try_catch_throw -TypeName:System.String -MemberName:extended_property -Force -MemberType:ScriptProperty -ErrorAction Stop
    demo_problem
    if($error[0].Exception.Message -eq "caught an exception")
    {
        throw "I only exist to trigger the catch block"
    }
    

    我什至试过这个都没用:

    Update-TypeData -Value:{try{&$script_block_try_catch_throw}catch{throw "Error!"}} -TypeName:System.String -MemberName:extended_property -Force -MemberType:ScriptProperty -ErrorAction Stop
    

    我很惊讶这不起作用。

    【讨论】:

    • 感谢您的尝试。当然,添加对 $Error 的检查确实不可行,因为这些块是扩展方法。要求开发人员记住哪些方法需要检查 $ERROR 无疑会失败。
    • +1 因为,如果 Keith Hill 是正确的,听起来这肯定是设计使然.... :(
    猜你喜欢
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    相关资源
    最近更新 更多