问题
In PowerShell, what is the difference between throw $ErrorMsg and $PScmdlet.ThrowTerminatingError($ErrorMsg)?
Are they same or different? If they are different which one is preferable?
回答1:
Throw creates a script-terminating (runspace-terminating) error, whereas $PScmdlet.ThrowTerminatingError() creates a statement-terminating error.
Note: These aren't official terms (the docs currently only vaguely reference terminating errors in the abstract, without scope), but they're useful for describing the de-facto behavior.
In short: By default,
a script-terminating error terminates the entire runspace, i.e., the running script and all its callers, with no further statements getting executed.
- The only way to intercept them is by using a
try/catchstatement (or, less commonly, atrapstatement).
- The only way to intercept them is by using a
whereas a statement-terminating error terminates only the current statement (the function calling
$PScmdlet.ThrowTerminatingError()and the statement it is a part of, which is often a pipeline), with execution continuing with the next statement.They too can be intercepted with
try/catch(ortrap), or ignored with the$ErrorActionPreferencepreference variable set toSilentlyContinue; by contrast, the-ErrorActioncommon parameter has no effect on them.Conversely, you can promote them to script-terminating errors with
$ErrorActionPreference = 'Stop', despite the docs claiming that$ErrorActionPreferencepertains only to nonterminating errors, the 3rd error type.
For more information, see this (unofficial) overview of PowerShell's error handling.
As for guidance when to use which type of error:
There is little guidance as to when to use
Throwin the about_Throw help topic; an example use case is given in whichThrowis used to abort a function/script in the absence of a mandatory parameter, as an alternative to PowerShell's default behavior of prompting for it.- Just be aware that
Throw, i.e., throwing a script-terminating error terminates the entire runspace (the running script and any of its callers), unless caught.
- Just be aware that
The Cmdlet Error Reporting article only discusses cmdlet-internal use with respect to when to report statement-terminating (called just "terminating" in the article) vs. nonterminating errors.
- A concise summary of the article can be found in this answer of mine.
Given the latter, you could argue that advanced functions - since they're like cmdlets - should at most report statement-terminating errors and that Throw (script-terminating errors) should be limited to scripts, but note that that contradicts the use of Throw to enforce mandatory parameters.
Perhaps the problematic distinction between script-terminating and statement-terminating errors is ultimately unintentional and perhaps the original intent was to only ever have script-terminating ones, which would explain why all the current documentation only ever talks about terminating errors in the abstract, without even mentioning the distinction.
来源:https://stackoverflow.com/questions/49204918/difference-between-throw-and-pscmdlet-throwterminatingerror