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?
The main difference between the Write-Error cmdlet and the throw keyword in PowerShell is that the former simply prints some text to the standard error stream (stderr), while the latter actually terminates the processing of the running command or function, which is then handled by PowerShell by sending out information ...
The throw keyword causes a terminating error. You can use the throw keyword to stop the processing of a command, function, or script. For example, you can use the throw keyword in the script block of an if statement to respond to a condition or in the catch block of a try - catch - finally statement.
The main difference between Write-Error and throw is that throw generates a terminating error, and Write-Error by default does not.
Throw. To create our own exception event, we throw an exception with the throw keyword. This creates a runtime exception that is a terminating error. It's handled by a catch in a calling function or exits the script with a message like this.
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.
try
/ catch
statement (or, less commonly, a trap
statement).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
(or trap
), or ignored with the $ErrorActionPreference
preference variable set to SilentlyContinue
; by contrast, the -ErrorAction
common 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With