看着PoshCode,http://poshcode.org/3226上的Get-WebFile脚本,我注意到了这个对我来说很奇怪的装置:
$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来表示非终止错误,并抛出来表示终止错误,所以在我看来,你不应该在Write-Error之后再使用Return。有什么不同吗?
发布于 2012-02-15 22:38:49
如果要通知用户非严重错误,则应使用Write-Error。默认情况下,它所做的就是在控制台上以红色文本打印一条错误消息。它不会阻止管道或循环的继续。另一方面,Throw会产生所谓的终止错误。如果你使用throw,流水线和/或当前循环将被终止。实际上,除非您使用trap或try/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。
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这里的一个问题是在ForEach-Object中使用return。它不会像预期的那样中断处理。
更多信息:
$ErrorActionPreference:try/catch:trap:throw:return:发布于 2016-10-10 06:08:43
重要信息: There 2 types of terminating errors,不幸的是,当前的帮助主题将它们混淆了
Throw触发,或者通过common -ErrorAction parameter、-ErrorAction Stop或$ErrorActionPreference preference variable、$ErrorActionPreference = 'Stop'升级其他错误类型之一。除非被捕获,否则它们将终止当前运行空间(线程);也就是说,如果为applicable).,则它们不仅终止当前脚本,还终止其所有调用者
有关PowerShell错误处理的全面概述,请参阅GitHub documentation issue #1583。
这篇文章的其余部分主要关注非终止错误与语句终止错误。
为了补充现有的有用答案,重点关注问题的核心:How do you choose 是否report a statement-terminating or error
Cmdlet Error Reporting包含有用的指南;让我尝试一个实用摘要
non-terminating errors背后的一般思想是允许对大型输入集进行“容错”处理:未能处理输入对象的子集不应(默认情况下)中止整个可能长时间运行的过程,从而允许您检查错误,并在以后仅重新处理 failed 对象-正如在自动变量$Error中收集的错误记录所报告的那样。
如果您的cmdlet /高级函数为:NON-TERMINATING ,则
错误
- **accepts MULTIPLE input objects**, via the pipeline input and/or array-valued parameters, AND
- **errors occur for SPECIFIC input objects**, AND
- **these errors DO NOT PREVENT PROCESSING of FURTHER input objects IN PRINCIPLE** (_situationally_, there may be no input objects left and/or previous input objects may already have been processed successfully).
- In advanced functions, use `$PSCmdlet.WriteError()` to report a non-terminating error (`Write-Error`, unfortunately, doesn't cause `$?` to be set to `$False` in the _caller's_ scope - see [GitHub issue #3629](https://github.com/PowerShell/PowerShell/issues/3629)).
- _Handling_ a non-terminating error: `$?` tells you whether the most recent command reported _at least one_ non-terminating error.
- Thus, `$?` being `$False` can either mean that _any (nonempty) subset_ of input objects weren't properly processed, possibly the entire set.
- Preference variable `$ErrorActionPreference` and/or common cmdlet parameter `-ErrorAction` can modify the behavior of non-terminating errors (only) in terms of error output behavior and whether non-terminating errors should be escalated to _script_-terminating ones.在
中,
- Notably, **if an error occurs in a cmdlet / advanced function that only accepts a SINGLE or NO input object and outputs NO or a SINGLE output object or takes** _**parameter input only**_ **and the parameter values given prevent meaningful operation.**
- In advanced functions, you must use `$PSCmdlet.ThrowTerminatingError()` in order to generate a statement-terminating error.
- Note that, by contrast, the `Throw` keyword generates a _script_-terminating error that aborts the _entire script_ (technically: the current _thread_).
- _Handling_ a statement-terminating error: A `try/catch` handler or `trap` statement may be used (which _cannot_ be used with _non-terminating_ errors), but note that even _statement_-terminating errors by default do not prevent the rest of the script from running. As with _non-terminating_ errors, `$?` reflects `$False` if the previous statement triggered a statement-terminating error.不幸的是,并非所有PowerShell自己的核心cmdlet都遵循这些规则
New-TemporaryFile (PSv5+)将报告一个非终止错误,尽管它不接受管道输入并且只生成一个输出对象-然而,这至少在PowerShell Core7.0中已经得到纠正:请参见GitHub issue #4634.Resume-Job的帮助声称传递不受支持的作业类型(例如使用Start-Job创建的作业,因为Resume-Job只适用于工作流作业)会导致终止错误,但从PSv5.1开始并非如此。发布于 2012-02-15 22:37:10
Write-Error cmdlet和PowerShell中的throw关键字之间的主要区别在于,前者只是将一些文本打印到standard error stream (stderr),而后者实际上是终止正在运行的命令或函数的处理,然后由PowerShell通过向控制台发送有关错误的信息来处理。
您可以在您提供的示例中观察到这两者的不同行为:
$URL_Format_Error = [string]"..."
Write-Error $URL_Format_Error
return在本例中,添加了return关键字,以便在将错误消息发送到控制台之后显式停止脚本的执行。另一方面,在第二个示例中,由于终止是由throw隐式完成的,因此return关键字不是必需的
$URL_Format_Error = New-Object System.FormatException "..."
Throw $URL_Format_Errorhttps://stackoverflow.com/questions/9294949
复制相似问题