Cmdlet.ThrowTerminatingError() is not affected by `-ErrorAction`
See original GitHub issueIf a cmdlet uses ThrowTerminatingError()
then that ErrorRecord is not affected by the common -ErrorAction
parameter. However, it is affected by $ErrorActionPreference
. This inconsistency is not a regression from Windows PowerShell 5.1, but is a cause of lots of user confusion. Note that -ErrorAction Break
DOES work because the code explicitly checks for that, but other values are not checked.
Steps to reproduce
Invoke-WebRequest https://foo.lskdjf -ErrorAction ignore
Expected behavior
Nothing
Actual behavior
Error printed
Environment data
Name Value
---- -----
PSVersion 7.2.0-preview.3
PSEdition Core
GitCommitId 7.2.0-preview.3
OS Darwin 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:17 (11 by maintainers)
Top Results From Across the Web
PowerShell ThrowTerminatingError() errors are not true ...
Note that -ErrorAction Stop does not help, it is not designed for such errors. It affects non-terminating errors ( WriteError() , Write-Error )....
Read more >Everything you wanted to know about exceptions
ThrowTerminatingError() is that it creates a terminating error within your Cmdlet but it turns into a non-terminating error after it leaves your ...
Read more >Can someone please explain this seemingly inconsistent ...
ThrowTerminatingError() API in cmdlets. They behave somewhat like a script-terminating error, but they will only stop the current pipeline ...
Read more >Read The Big Book of PowerShell Error Handling
NET method that throws an exception, a Cmdlet or Advanced Function that produce non-terminating errors when ErrorAction is set to Stop, and an...
Read more >Analysis of Error Handling Test Results
The final section tests how PowerShell behaves when it encounters unhandled terminating errors from each possible source (a Cmdlet that uses PSCmdlet.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
The full phrase “the current thread of execution” is unfortunately sorta needed there as it doesn’t actually terminate the thread (in 99.99% of cases). It’s difficult to come up with good terminology for this. Maybe “call stack terminating”? That’s going to be mostly meaningless to a lot of folks probably.
Following discussions in #19500 there’s a clarification / pedantic point to add. That issue concerns something different - if the current $errorActionPreference in a function, set by -ErrorAction or inherited from the caller, is silently continue
throw
is considered to becaught
and handled silently, and execution continues. But it also strayed into-ErrorAction
working / not working and ErrorActionPreference.I think the initial post mis-explains the behaviour
consider this code
It sets
$ErrorActionPreference
- so, according to the initial description, we would expect the error to be supressed but in practice:Whatever this error is returned to does what
$errorActionPreference
says it should do. So if the function is called from a second function:Execution continues back in the calling function after printing the error if the preference is continue.
Execution continues back in the calling function WITHOUT printing the error if the preference is SILENTLYcontinue.
And it stops without printing “returned to bar” if the preference is STOP.
As already pointed out by @mklement0 et al. “terminating” errors have multiple varieties
If I change the first function to use
throw
the message “returned to bar” isn’t printedbut if the error-action-preference is
silentlycontinue
the throw is caught immediately.This creates problems for people writing and calling functions. For writers calling
$pscmdlet.ThrowTerminatingError()
side steps-ErrorAction
(think of that as “do X when an error is thrown to you” and theThrowTerminatingError
as “throw an error to your caller”) , andthrow
stops other code running in the calling script - so without try{} Catch{} any clean up is missed.For callers
-ErrorAction silently continue
works for some errors, but for a throw it can cause the function code to continue and do something harmful (e.g. in$x = get-thingName; if (-not $x) {throw} ; delete-thing -name "$x*"
-errorAction SilentlyContinue would delete every thing) .