Ответ 1
-ErrorAction Stop
меняет вещи для вас. Попробуйте добавить это и посмотреть, что вы получаете:
Catch [System.Management.Automation.ActionPreferenceStopException] {
"caught a StopExecution Exception"
$error[0]
}
Недавно я написал сценарий PowerShell, который прекрасно работает - однако я хотел бы сейчас обновить сценарий и добавить некоторую проверку/обработку ошибок - но я, кажется, был озадачен первым препятствием. Почему не работает следующий код?
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"
}
Ошибка перехватывается во втором блоке перехвата - вы можете увидеть вывод из $error[0]
. Очевидно, я хотел бы поймать его в первом блоке. Что мне не хватает?
-ErrorAction Stop
меняет вещи для вас. Попробуйте добавить это и посмотреть, что вы получаете:
Catch [System.Management.Automation.ActionPreferenceStopException] {
"caught a StopExecution Exception"
$error[0]
}
Это очень странно.
Я прошел базовые классы ItemNotFoundException
и протестировал следующие несколько catch
es, чтобы увидеть, что поймал его:
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'
}
Как оказалось, выход был 'RuntimeException'
. Я также попробовал это с другим исключением CommandNotFoundException
:
try {
do-nonexistent-command
}
catch [System.Management.Automation.CommandNotFoundException] {
write-host 'CommandNotFoundException'
}
catch {
write-host 'well, darn'
}
Правильно выводит 'CommandNotFoundException'
.
Я смутно помню, как читал в другом месте (хотя я не мог найти его снова) о проблемах с этим. В таких случаях, когда фильтрация исключений работала некорректно, они могли бы найти ближайший Type
, а затем использовать switch
. Следующие просто ловит Exception
вместо RuntimeException
, но эквивалент switch
моего первого примера, который проверяет все базовые типы 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'}
}
}
Это записывает 'ItemNotFound'
, как и должно быть.