我认为我在PowerShell 4.0异常处理中发现了一个令人讨厌的错误,但我是PowerShell脚本的新手,并希望确保我没有错过任何东西。
我设法找到了一个可以重现问题的代码:
foreach ($id in 1..20) {
try {
# The objective is to generate basic exceptions and see how they are caught
throw "#$id"
}
# Oddly, if the following block is removed or commented, there is no problem
catch [System.ArithmeticException] {
Write-Host ("[ArithmeticException] {0}" -f $_.Exception.Message)
throw
}
# Problem is, at some point in time, the following catch block is run,
# even if the exception is not a System.ArgumentException
catch [System.ArgumentException] {
Write-Host ("[ArgumentException] {0}" -f $_.Exception.Message)
if ($_.Exception.GetType().Name -ne "ArgumentException") {
Write-Warning ("Expected [ArgumentException] but got [{0}]" -f $_.Exception.GetType().Name)
}
}
# The exceptions should all be caught here
catch {
Write-Host ("[Generic] {0}" -f $_.Exception.Message)
}
}
基本上,我有一个带有3个catch {}块的try {}:
第一个catch {}只是重新抛出一个特定的异常。永远不应该执行它,因为永远不会生成该异常。
第二个catch {}记录特定异常的消息。永远不应该执行它,因为永远不会生成该异常。
第三个捕获{}是默认值。它应该始终执行。
运行此代码的预期结果如下:
[Generic] #1
[Generic] #2
...
[Generic] #20
这是我第一次执行剧本时得到的。
然而,在执行了不同数量的脚本(通常是2或3)后,我得到了这个:
[ArgumentException] #2
WARNING:Expected [ArgumentException] but got [RuntimeException]
这意味着执行第二个catch {}块而不是第三个。
一旦发生这种情况(id可能会有所不同),它会发生,直到我关闭PowerShell主机并启动一个新主机。到目前为止,我可以在Windows 7 32位桌面和Windows 2012 R2服务器上重现该问题。
如果它不够奇怪,如果我删除第一个catch {}块,问题就会消失。
那么,我错过了什么或者它是一个错误吗?
答案 0 :(得分:0)
我可以按照问题注释中的建议从$PSVersionTable
开始循环,通过一次尝试就可以在最新的PS 5上对此进行重现(根据1.100
,为5.0.10586.117。< / p>
确实似乎已在PS Core中修复;我无法在6.0.3上重现它。循环总是进入[Generic]
catch块。
在PS UserVoice论坛上似乎已经有a bug about this。此错误引用了this now-unavailable Connect item,,而该错误又引用了this other SO question,与您的问题类似。将这两个SO问题/代码示例直接链接到UserVoice可能是值得的。