PowerShell执行错误的异常处理程序 [英] PowerShell executes the wrong exception handler
问题描述
我认为我在PowerShell 4.0异常处理中发现了一个令人讨厌的错误,但是我是PowerShell脚本的新手,并希望确保自己不会错过任何内容.
I think I have found a nasty bug in PowerShell 4.0 exception handling but I'm new to PowerShell scripting and want to be sure I didn't miss something.
我设法找到了重现该问题的代码:
I managed to find a code that reproduces the problem:
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 {}:
Basically, I have a try{} with 3 catch{} blocks:
-
第一个catch {}只是抛出一个特定的异常.永远不要执行它,因为永远不会产生异常.
The first catch{} just rethrows a specific exception. It should never be executed as that exception is never generated.
第二个catch {}记录特定异常的消息.永远不要执行它,因为永远不会产生异常.
The second catch{} logs the message of a specific exception. It should never be executed as that exception is never generated.
第三个捕获{}是默认捕获.它应该始终执行.
The third catch{} is the default one. It should be always executed.
运行此代码的预期结果如下:
The expected result of running this code is as follow:
[Generic] #1
[Generic] #2
...
[Generic] #20
这是我第一次执行脚本所得到的.
And it is what I get for the first executions of the script.
但是,在执行了不同数量的脚本(通常是2或3)之后,我得到了:
However, after a varying number of executions of the script (usually 2 or 3), I get this :
[ArgumentException] #2
WARNING:Expected [ArgumentException] but got [RuntimeException]
这意味着将执行第二个catch {}块,而不是第三个.
It means the second catch{} block is executed instead of the third.
一旦发生这种情况(ID可能会有所不同),直到我关闭PowerShell主机并启动一个新主机为止.到目前为止,我可以在Windows 7 32位桌面和Windows 2012 R2服务器上重现该问题.
Once this occurs (the id may vary), it happens until I close the PowerShell host and start a new one. So far, I can reproduce that problem on a Windows 7 32bits desktop and a Windows 2012 R2 server.
如果还不够奇怪,那么如果我删除第一个catch {}块,问题就会消失.
If it wasn't odd enough, the problem disappears if I remove the first catch{} block.
那么,我错过了什么还是一个错误吗?
So, have I missed something or is it a bug ?
推荐答案
我可以通过使循环从1.100
如问题注释中所建议.
I can repro this on the latest PS 5 as of now (5.0.10586.117 according to $PSVersionTable
) with a single attempt by making the loop run from 1.100
as suggested in the question's comments.
确实似乎已在PS Core中修复;我无法在6.0.3上重现它.循环总是进入[Generic]
catch块.
It does appear to have been fixed in PS Core; I could not reproduce it on 6.0.3. The loop always enters the [Generic]
catch block.
似乎确实有此现在不可用的Connect项,它依次引用
There does appear to be a bug about this on the PS UserVoice forum already. This bug references this now-unavailable Connect item, which in turn references this other SO question with a similar issue as yours. It's probably worth linking both these SO questions / code samples to the UserVoice directly.
这篇关于PowerShell执行错误的异常处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!