PowerShell tr​​y catch 中不匹配的异常类型详细信息

Exception type details not matching in PowerShell try catch

我正在尝试找到一种方法来构建具有各种可能的异常类型的 try catch 块。我从其他问题中得到了一些线索来检查$Error[0].Exception.GetType().FullName

但是,我仍然无法弄清楚从哪里获得必须放在 catch 关键字前面的异常 class 类型。

例如,当我尝试:

try { 1/0 } catch { $Error[0].Exception.GetType().FullName }

我得到:

System.Management.Automation.RuntimeException

然而,当我在运行下面时:

try { 1/0 } catch [DivideByZeroException]{ "DivideByZeroException" } catch { $Error[0].Exception.GetType().FullName }

我得到:

DivideByZeroException

在上述情况下,$Error[0] 中的 [DivideByZeroException] 在哪里?

因为我在$Error[0]的属性中找不到它:

PS C:\Temp> $Error[0] | Select *


PSMessageDetails      : 
Exception             : System.Management.Automation.RuntimeException: Attempted to divide by zero. 
                        ---> System.DivideByZeroException: Attempted to divide by zero.
                           --- End of inner exception stack trace ---
                           at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(
                        FunctionContext funcContext, Exception exception)
                           at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(Int
                        erpretedFrame frame)
                           at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction
                        .Run(InterpretedFrame frame)
                           at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction
                        .Run(InterpretedFrame frame)
TargetObject          : 
CategoryInfo          : NotSpecified: (:) [], RuntimeException
FullyQualifiedErrorId : RuntimeException
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}

DivideByZeroException实例存储在.InnerException属性中,.Exception属性值存储在System.Management.Automation.ErrorRecord实例中$Error[0],反映最近的错误:

PS> try { 1 / 0 } catch {}; $Error[0].Exception.InnerException.GetType().FullName

System.DivideByZeroException

RuntimeException wraps the DivideByZeroException异常。

看起来,因为您使用的是 类型限定的 catch 块,所以在 catch 块内, [ErrorRecord] 实例反映在 automatic $_ variable contains the specified exception directly in .Exception - unlike in the corresponding entry in the automatic $Error variable:

PS> try { 1 / 0 } catch [DivideByZeroException] { 
      $_.Exception.GetType().FullName; 
      $Error[0].Exception.GetType().FullName 
    }

System.DivideByZeroException                  # type of $_.Exception
System.Management.Automation.RuntimeException # type of $Error[0].Exception

换句话说:

  • 不合格 catch块中,$_ 等价于 $Error[0](后者也可以在 later 中访问),并包含 .Exception 中的(外部)异常和 - 如果适用 - .Exception.InnerException 中的内部异常.

  • type-qualified catch 块中,你可以捕获一个 inner 异常 - 作为(后来)直接反映在 $Error[0].Exception.InnerException - 中,在这种情况下,限定 catch 块内的 $_.Exception 包含该内部异常。