Ich habe kürzlich ein PowerShell-Skript geschrieben, das hervorragend funktioniert. Ich möchte das Skript jedoch jetzt aktualisieren und einige Fehlerprüfungen/-behandlungen hinzufügen. Die erste Hürde scheint jedoch überwunden zu sein. Warum funktioniert der folgende Code nicht?
try {
Remove-Item "C:\somenonexistentfolder\file.txt" -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
"item not found"
}
catch {
"any other undefined errors"
$error[0]
}
finally {
"Finished"
}
Der Fehler wird im zweiten catch-Block abgefangen - Sie können die Ausgabe von $error[0]
Sehen. Offensichtlich möchte ich es im ersten Block fangen. Was vermisse ich?
-ErrorAction Stop
ändert die Dinge für Sie. Versuchen Sie dies hinzuzufügen und sehen Sie, was Sie bekommen:
Catch [System.Management.Automation.ActionPreferenceStopException] {
"caught a StopExecution Exception"
$error[0]
}
Das ist sehr seltsam.
Ich habe die Basisklassen von ItemNotFoundException
durchgesehen und die folgenden multiplen catch
es getestet, um zu sehen, was würde fängt:
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'
}
Wie sich herausstellte, war die Ausgabe 'RuntimeException'
. Ich habe es auch mit einer anderen Ausnahme versucht CommandNotFoundException
:
try {
do-nonexistent-command
}
catch [System.Management.Automation.CommandNotFoundException] {
write-Host 'CommandNotFoundException'
}
catch {
write-Host 'well, darn'
}
Dieser Ausgang 'CommandNotFoundException'
richtig.
Ich erinnere mich vage, wie ich an anderer Stelle gelesen habe (obwohl ich es nicht wieder finden konnte), dass ich Probleme damit hatte. In solchen Fällen, in denen die Ausnahmefilterung nicht richtig funktioniert hat, haben sie das nächstgelegene Type
abgefangen und dann ein switch
verwendet. Das Folgende fängt nur Exception
anstelle von RuntimeException
ab, ist aber das switch
Äquivalent meines ersten Beispiels, das alle Basistypen von ItemNotFoundException
prüft:
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'}
}
}
Dies schreibt 'ItemNotFound'
, so wie es sollte.