PowerShell попробуйте / поймать / наконец - PullRequest
43 голосов
/ 21 июля 2011

Я недавно написал сценарий 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]. Очевидно, я хотел бы поймать его в первом блоке. Чего мне не хватает?

Ответы [ 2 ]

35 голосов
/ 21 июля 2011

-ErrorAction Stop меняет вещи для вас. Попробуйте добавить это и посмотреть, что вы получите:

Catch [System.Management.Automation.ActionPreferenceStopException] {
"caught a StopExecution Exception" 
$error[0]
}
28 голосов
/ 21 июля 2011

Это очень странно.

Я прошел базовые классы 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', какэто должно.

...