问题
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)
}
}
Basically, I have a try{} with 3 catch{} blocks:
The first catch{} just rethrows a specific exception. It should never be executed as that exception is never generated.
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.
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]
It means the second catch{} block is executed instead of the third.
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.
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:
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.
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.
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.
来源:https://stackoverflow.com/questions/36767970/powershell-executes-the-wrong-exception-handler