Difference between throw and $pscmdlet.ThrowTerminatingerror()? Difference between throw and $pscmdlet.ThrowTerminatingerror()? powershell powershell

Difference between throw and $pscmdlet.ThrowTerminatingerror()?


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 / 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.

    • 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.
  • 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.