1. ホーム
  2. powershell

[解決済み] Write-ErrorとThrowはいつ使い分ける?終端エラーと非終端エラー

2022-03-06 07:26:54

質問

PoshCodeのGet-WebFileスクリプトを見ているところです。 http://poshcode.org/3226 私はこの奇妙な仕掛けに気づきました。

$URL_Format_Error = [string]"..."
Write-Error $URL_Format_Error
return

これに対して、次のような理由は何でしょうか。

$URL_Format_Error = [string]"..."
Throw $URL_Format_Error

あるいはもっといい。

$URL_Format_Error = New-Object System.FormatException "..."
Throw $URL_Format_Error

私の理解では、終了しないエラーにはWrite-Errorを、終了するエラーにはThrowを使うべきで、Write-Errorの後にReturnを使うべきではないように思えますが、いかがでしょうか?何か違いがあるのでしょうか?

どのように解決するのですか?

Write-Error は、重大ではないエラーをユーザーに知らせたい場合に使用します。デフォルトでは、コンソールに赤い文字でエラーメッセージが表示されるだけです。パイプラインやループの継続を止めることはありません。 Throw 一方で、いわゆるターミネーティングエラーを発生させます。throwを使うと、パイプラインや現在のループが終了してしまいます。実際、すべての実行は、あなたが trap または try/catch 構造体を用いて終了時のエラーを処理する。

1つだけ注意点があり、もしあなたが $ErrorActionPreference から "Stop" を使用し Write-Error となります。 終了エラー .

リンク先のスクリプトには、このように書かれています。

if ($url.Contains("http")) {
       $request = [System.Net.HttpWebRequest]::Create($url)
}
else {
       $URL_Format_Error = [string]"Connection protocol not specified. Recommended action: Try again using protocol (for example 'http://" + $url + "') instead. Function aborting..."
       Write-Error $URL_Format_Error
    return
   }

その関数の作者は、その関数の実行を停止して画面にエラーメッセージを表示したかったようですが、スクリプト全体の実行を停止させたくはなかったようです。スクリプトの作者は throw を使用する必要があります。 try/catch を呼び出すと、その関数が表示されます。

return は、関数、スクリプト、スクリプトブロックなどの現在のスコープを終了します。これは、コードで説明するのが一番わかりやすいでしょう。

# A foreach loop.
foreach ( $i in  (1..10) ) { Write-Host $i ; if ($i -eq 5) { return } }

# A for loop.
for ($i = 1; $i -le 10; $i++) { Write-Host $i ; if ($i -eq 5) { return } }

両方に出力します。

1
2
3
4
5

ここで一つ注意しなければならないのは returnForEach-Object . 期待するような処理の破綻はありません。

詳細はこちら