The different methods PowerShell exposes to terminate a script are not entirely consistent.
When throw is used to raise a terminating error, it will stop the current script and anything which called it. In the following example, child2 will never execute:
$ErrorActionPreference = 'Continue' function caller { child1 child2 } function child1 { throw 'Failed' 'child1' } function child2 { 'child2' } caller
When the ThrowTerminatingError method is used, processing within child1 stops, but the function caller continues. This is demonstrated as follows:
function caller { child1 child2 } function child1 { [CmdletBinding()] param ( ) $errorRecord = New-Object Management.Automation.ErrorRecord( (New-Object Exception('Failed')), 'ID', 'OperationStopped', $null ) $pscmdlet.ThrowTerminatingError($errorRecord) 'child1' } function child2 { 'child2' }
Executing the function caller shows that child2 is executed:
child1 : Failed
At line:2 char:5
+ child1
+ ~~~~~~
+ CategoryInfo : OperationStopped: (:) [child1], Exception
+ FullyQualifiedErrorId : ID,child1
child2
The behavior of the preceding example is equivalent to the behavior seen when calling Cmdlets. For example, the command ConvertFrom-Json raises a terminating error when the content it is asked to convert is invalid.
When a Cmdlet throws a terminating error within another function, the caller script continues to execute unless ErrorAction is set to Stop:
function caller { ConvertFrom-Json -InputObject '{{' child1 } function child1 { 'Called' } caller
The same behavior is seen when calling .NET methods, shown as follows. The static method IPAddress.Parse will raise a terminating error because the use of the method is not valid:
function caller { [IPAddress]::Parse('this is not an IP') child1 } function child1 { 'Called' } caller