Вывод для try / catch в классах Powershell
Экспериментируя с использованием классов в PowerShell, я не уверен, как отображать вывод. Например, в этом блоке кода ошибка записи не отображает сообщение об ошибке:
class Test {
[string] $test
Test ([string] $test) {
$this.test = $test
}
[test] Testfail() {
try {
Get-Childitem F:\ -ErrorAction stop
} catch {
Write-Host "ERROR!!! $this.test"
Exit 1
}
return $this.test + "not an error!"
}
}
В этом случае очевидно, что код запускает оператор catch при выходе из окна PowerShell, но если я закомментирую Exit 1, сообщение Write-Host не отображается. Может кто-нибудь объяснить, как выводить ошибку?
1 ответ
Только когда-либо использовать exit
для выхода из файлов сценария (*.ps1
), а не методы или функции класса.
Вызов exit
из метода или функции класса мгновенно выйдет из процесса PowerShell в целом.
Чтобы сообщить об ошибке из метода класса, используйте завершающую ошибку, которая-ErrorAction Stop
или Throw
оператор генерировать.
То есть просто используйте Get-Childitem F:\ -ErrorAction stop
без try
/ catch
, что вызывает завершающую ошибку (runspace-), которую вызывающий должен уловить.
Если, напротив, вы просто хотите выдать сообщение об ошибке в своем методе, не влияя на поток выполнения, обратите внимание, что вы не можете использоватьWrite-Error
из метода класса; однако вы можете использоватьWrite-Warning
(Write-Host
тоже работает, но использовать его не рекомендуется).
- Предупреждение: нельзя использовать вслепую
return
для выхода из метода, если это не[void]
-типированный. Вы вынуждены вернуть экземпляр объявленного возвращаемого типа, а покаreturn $null
хорошо подходит для обозначения "не возвращаемого значения" для ссылочных типов, используяreturn $null
с типом значения, таким как[int]
или[datetime]
либо преобразует$null
к этому типу (в результате0
для типа возврата[int]
) или разрывы (для возвращаемого типа[datetime]
, потому как$null
не могут быть осмысленно преобразованы в этот тип).
Вкратце: методы класса в PowerShell ведут себя иначе, чем другой код PowerShell:
Для записи в поток вывода успеха вы должны использовать
return
заявление; неявный вывод не поддерживается.Чтобы сообщить об ошибке, вы должны сгенерировать завершающую ошибку либо через общий параметр
-ErrorAction Stop
, аThrow
выражение или вызов метода.NET, который генерирует исключение; непрекращающиеся ошибки и попытки записи в поток ошибок напрямую сWrite-Error
незаметно игнорируются.Однако все остальные выходные потоки (см. About_redirection) проходят.
Это, возможно, неожиданное несоответствие обсуждается в этом выпуске GitHub, а запрос на разъяснение поведения в документации можно найти в этом выпуске документации GitHub.