一尘不染

我什么时候应该使用 Write-Error 与 Throw?终止与非终止错误

all

查看 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。有区别吗?


阅读 48

收藏
2022-09-06

共1个答案

一尘不染

Write- Error如果您想通知用户非严重错误,则应使用。默认情况下,它所做的只是在控制台上以红色文本打印错误消息。它不会阻止管道或循环继续。Throw另一方面产生所谓的终止错误。如果你使用
throw,管道和/或当前循环将被终止。实际上,除非您使用 atraptry/catch结构来处理终止错误,否则所有执行都将终止。

有一点需要注意,如果你设置 $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在调用函数时使用
a 。

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

这里的一个问题是使用returnwith ForEach-Object。它不会像人们预期的那样中断处理。

更多信息:

2022-09-06