New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cmdlet.ThrowTerminatingError() is not affected by -ErrorAction
#14819
Comments
I've always been confused as to what |
@jborean93, please see MicrosoftDocs/PowerShell-Docs#1583 |
I do think a change here would in the long run be an overall positive change, and I'd like to see it personally. I'm not sure what you could actually change here without causing some real weird breaks though. It seems like a significantly higher risk than what y'all would typically go for. |
Here's a possible way forward:
|
Some history/context: @mklement0 wrote:
They are absolutely by design. Statement terminating exceptions are intended to mimic shell semantics. An error in a pipeline (optionally) writes a message then terminates the pipeline and sets Now PowerShell error objects are much richer than traditional shell errors so one of the scenarios we had in mind was error recovery/remediation based on the contents of the error records. For example, if you're deleting a lot of files and there are some failures, the error records record which files were not deleted and why. This allows you to take additional actions in the script to delete those files. Error disposition is also much richer in PowerShell through PowerShell 1.0 also had Unfortunately And one more dimension of complexity - expressions vs commands. For performance reasons, an expression is not evaluated in the context of the pipeline processor so it has slightly different error semantics. Philosophically, our goal was such that if you wrote shell-style code, then you would get (enhanced) shell semantics and if you wrote programmer-style code (implied by the use of This doesn't mean that there aren't bugs (there are) or that we got the design totally right. However, tweaking the existing semantics without a total scenario review is unlikely to make things better, just different implying new confusion not less confusion. I do think it would be interesting to do the full scenario review and see if a new "error mode" makes sense. (Note: if we did an error mode it would have to be a compile-time switch i.e.
Yes - this is the preferred terminology. 'Runspace terminating' is inaccurate as the error doesn't "terminate" the runspace, just the currently executing set of statements i.e. the script. |
This comment has been minimized.
This comment has been minimized.
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. |
This comment has been minimized.
This comment has been minimized.
@BrucePay, there are multiple problematic aspects with PowerShell's current error handling, so why not take this opportunity to perform the full scenario review you propose:
As you state, a change in this area would inevitably be breaking and require an opt-in; a concern regarding a
It is the non-terminating errors that mimic shell semantics, while offering additional features (log of errors in
These shells themselves have no concept of statement-terminating errors (although individual executables can choose to abort pipeline processing by closing their end of the pipe prematurely). PowerShell's statement-terminating errors offer a way to abort a pipeline instantly, as a whole, in case an error condition so severe is encountered that further pipeline processing makes no sense. Statement-terminating errors also occur in expressions, such as when .NET methods throw an exception. The question is whether it is helpful to by default terminate only the pipeline / statement being executed. To me, it isn't: given that it indicates an error condition that is severe, the more sensible behavior is to terminate the script. That is, we can make do without the concept of a statement-terminating error and only have one type of terminating error: the script-terminating error:
I believe that this, along with integrating external-executable calls (treat nonzero exit codes as non-terminating errors, but escalate to script-terminating with |
When talking about implementation, "pipeline" is probably the word to use there. It would be confusing to use in documentation, but a pipeline is sort of the rawest measurement of a unit of execution in PowerShell. For example, this code: PowerShell.Create().AddCommand("Get-ChildItem").Invoke()
// or more similar to what ConsoleHost does:
using var pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(new Command("Get-ChildItem", isScript: false));
pipeline.Invoke(); There's no script there, it's just a pipeline processor that looks up the command info and creates a command processor. None of this is to say that "script-terminating" isn't the right term to use for docs, I honestly don't know. Just giving you the full picture.
I would say that is generally a good way to look at it, and probably a good way to present it when not talking about implementation specifics. If we were being the absolute strictest of nitpicky, the thread is only terminated when one of these happens:
(P.S. I wrote this before your second post but then got distracted. I still haven't read the second one FYI, so sorry if my delayed answer equated to more work or something) |
I appreciate the detailed explanation, @SeeminglyScience - I've hidden my previous comments on that topic. |
@PowerShell/powershell-committee reviewed this, we agree that the intent of |
No, That is, if we resolved this simply by making
I may have mentioned this before, but if we simplified the model to only two types of errors: fatal (the current script-terminating ones) and non-fatal (non-terminating), these asymmetries and headaches would go away. Since a breaking change is required either way, I suggest breaking things in a more useful manner. |
@mklement0 I agree it may be worth while to consider a proposal that is breaking, but would avoid user confusion for the next "10 years". We should certainly continue that conversation. The @PowerShell/powershell-committee did discuss the need to use |
Understood, @SteveL-MSFT, but my point was that even limiting ourselves to fixing the bug (from the perspective of the original design intent):
To put it differently: we have a major break on our hands either way (which will require an opt-in); the bug fix is not worth making, and I suggest taking the opportunity to get it right for the next "10 years". |
Following discussions in #19500 there's a clarification / pedantic point to add. I think the initial post mis-explains the behaviour consider this code
It sets
Whatever this error is returned to does what
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
but if the error-action-preference is
This creates problems for people writing and calling functions. |
Continuing discussions in #19500 The following idea occurred to me.
I haven't thought through all the possible wrinkles with this, but it might ease the problem. |
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
1 similar comment
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you. |
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes. |
If 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
Expected behavior
Actual behavior
Environment data
The text was updated successfully, but these errors were encountered: