PowerShell try/catch/finally
-ErrorAction Stop
is changing things for you. Try adding this and see what you get:
Catch [System.Management.Automation.ActionPreferenceStopException] {"caught a StopExecution Exception" $error[0]}
That is very odd.
I went through ItemNotFoundException
's base classes and tested the following multiple catch
es to see what would catch it:
try { remove-item C:\nonexistent\file.txt -erroraction stop}catch [System.Management.Automation.ItemNotFoundException] { write-host 'ItemNotFound'}catch [System.Management.Automation.SessionStateException] { write-host 'SessionState'}catch [System.Management.Automation.RuntimeException] { write-host 'RuntimeException'}catch [System.SystemException] { write-host 'SystemException'}catch [System.Exception] { write-host 'Exception'}catch { write-host 'well, darn'}
As it turns out, the output was 'RuntimeException'
. I also tried it with a different exception CommandNotFoundException
:
try { do-nonexistent-command}catch [System.Management.Automation.CommandNotFoundException] { write-host 'CommandNotFoundException'}catch { write-host 'well, darn'}
That output 'CommandNotFoundException'
correctly.
I vaguely remember reading elsewhere (though I couldn't find it again) of problems with this. In such cases where exception filtering didn't work correctly, they would catch the closest Type
they could and then use a switch
. The following just catches Exception
instead of RuntimeException
, but is the switch
equivalent of my first example that checks all base types of ItemNotFoundException
:
try { Remove-Item C:\nonexistent\file.txt -ErrorAction Stop}catch [System.Exception] { switch($_.Exception.GetType().FullName) { 'System.Management.Automation.ItemNotFoundException' { write-host 'ItemNotFound' } 'System.Management.Automation.SessionStateException' { write-host 'SessionState' } 'System.Management.Automation.RuntimeException' { write-host 'RuntimeException' } 'System.SystemException' { write-host 'SystemException' } 'System.Exception' { write-host 'Exception' } default {'well, darn'} }}
This writes 'ItemNotFound'
, as it should.