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?
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?
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 by default, i.e., the running script and all its callers, with no further statements getting executed; in other words: unless such an error is caught or suppressed, it is fatal.
They can be caught with a try
/ catch
statement (or, less commonly, a trap
statement).
They can be suppressed with by setting the $ErrorActionPreference
preference variable to 'SilentlyContinue'
, or - in PowerShell (Core) 7+ only - to 'Ignore'
.
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 by default.
They can be caught or suppressed in the same way that script-terminating errors can, but note that the common -ErrorAction
parameter has no effect on them.
Conversely, you can promote them to script-terminating errors with $ErrorActionPreference = 'Stop'
, despite the docs claiming that $ErrorActionPreference
pertains only to nonterminating errors, the 3rd error type (to which the -ErrorAction
parameter exclusively applies).
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 Throw
in the about_Throw
help topic; an example use case is given in which Throw
is 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.
Throw
, i.e., throwing a script-terminating error terminates the entire runspace (the running script and any of its callers), unless caught.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.
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.