Вывод для 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.

Другие вопросы по тегам