PowerShell捕获异常类型

7
有没有方便的方法来捕获try-catch目的中的异常类型和内部异常?
示例代码:
$a = 5
$b = Read-Host "Enter number" 
$c = $a / $b #error if $b -eq 0
$d = get-content C:\I\Do\Not\Exist

第三行会生成一个带有内部异常的运行时错误(编辑:修正此命令 $Error[1].Exception.InnerException.GetType()),第四行将生成一个“标准”(?)类型的异常($Error[0].Exception.GetType())。

是否可能使用同一行代码从这两个中获得所需的结果?

Ad1:来自第三行的错误

At -path-:3 char:1

+ $c = $a / $b #error if $b -eq 0
+ ~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

广告2:第4行出现错误

get-content : Cannot find path 'C:\I\Do\Not\Exist' because it does not exist.

At -path-:4 char:6

+ $d = get-content C:\I\Do\Not\Exist

+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (C:\I\Do\Not\Exist:String) 
[Get-Content], ItemNotFoundException    
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

编辑说明:为了明确,我希望结果以某种方式返回DivideByZeroException和ItemNotFoundException。


你尝试过使用 $ErrorActionPreference = "Continue" 吗?这样可以让代码在错误情况下继续运行。 - Shadowzee
我认为你弄错了$Error[1].InnerException - 没有这样的属性。你可以像处理其他错误一样使用$Error[1].Exception。我不确定你想要什么。 - marsze
@marsze 不好意思,应该是$Error[1].Exception.InnerException.GetType()。 - Jlisk
2个回答

9

首先,您可以明确捕获特定的异常类型:

$ErrorActionPreference = "Stop"

try {
    1 / 0
}
catch [System.DivideByZeroException] {
    $_.Exception.GetType().Name
}

try {
    Get-Item "c:\does-not-exist"
}
catch [System.Management.Automation.ItemNotFoundException] {
    $_.Exception.GetType().Name
}
DivideByZeroException 基本上只是 RuntimeException 的 InnerException,理论上,InnerExceptions 可以无限嵌套:
catch {
    $exception = $_.Exception
    do {
        $exception.GetType().Name
        $exception = $exception.InnerException
    } while ($exception)
}

但是你可以将RuntimeException作为一个特殊情况来处理。即使PowerShell也是这样做的。看看第一个代码示例。即使指定了内部异常的类型,catch块也会被执行。

你也可以自己做类似的事情:

catch {
    $exception = $_.Exception
    if ($exception -is [System.Management.Automation.RuntimeException] -and $exception.InnerException) {
        $exception = $exception.InnerException
    }
    $exception.GetType().Name
}

注意,如果您想捕获两个异常,请为每个命令使用一个try-catch。否则,如果第一个失败,第二个将不会被执行。此外,您必须将$ErrorActionPreference指定为"Stop",以便捕获非终止异常。


1
这个回答很好,无限嵌套的InnerExceptions解释了为什么一个相对简单的命令无法确定类型。我可能会将此代码用作查找异常类型,希望你不介意。 - Jlisk
1
你可以考虑使用FullName代替Name,这样可以获取命名空间。 - undefined

0

我正在尝试制造错误,并从中提取要放入括号中的内容。最好只用一个命令。 - Jlisk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接