-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Why do handled exceptions show in ErrorVariable? #3768
Comments
Good catch (accidental pun). Note that another quirk comes into play here:
|
$Error was originally conceived as a running log of all errors that happened in your script, including exceptions that were caught or when ErrorAction was set to SilentlyContinue The goal was primarily for forensics analysis after your script had been run. (Note: this goal of recording all errors was muted somewhat by the introduction of -ErrorAction ignore where the error isn't written into the error variable.) |
Perhaps a non-breaking change is we could add a |
@BrucePay and the -ErrorVariable must mirror that? I mean, I'm ok with everything being in $Error ... @SteveL-MSFT I guess that would at least give us a way ... Right now I do not think there is a way to hide errors, and also tell whether or not a command was successful. |
The @PowerShell/powershell-committee had a very interesting conversation around this, it's difficult to know which way we should go with this. Could you explain in more detail why this is important to you? Is it simply that you're trying to drill the error variable down to zero as you test your code and try to catch all exceptions? |
I obviously can't speak for @Jaykul, but here's my 0.0178236 EUR (using today's exchange rate): There are two conceivable scenarios (not mutually exclusive):
(a), even though it should be covered by automatic variable
(b) is currently not a reliable option, because examining the |
@PowerShell/powershell-committee reviewed this (@BrucePay was absent from discussion) and agreed this change where |
There are some related data points here that are worth highlighting as part of this discussion before breaking them out into their own issues. It seems some other use cases surrounding error handling are resulting in confusion as well. For example, if you invoke PowerShell using the $ps = [PowerShell]::Create()
$ps.AddCommand('Get-Service').AddParameter('Name','Invalid').AddParameter('ErrorAction',[System.Management.Automation.ActionPreference]::Ignore) > $null
$ps.Invoke()
$ps.HadErrors # returns $true; expectation is that this would return false since the command was configured to ignore errors You can see the same behaviour via direct command invocation in PowerShell: Get-Service -Name Invalid -ErrorAction Ignore
$? # returns $false; shouldn't this return $true? In both of these cases, |
Just to clarify: does that mean that caught errors will be absent from Note that if such errors are still recorded in |
I'm also inclined to think that Given that terminating errors (those that can be caught with On a side note: |
@mklement0 I think you're confusing the use case. Are you suggesting that it's ok that an application that uses the PowerShell class to invoke scripts for automation would need to inject script wrappers around scripts provided by end-users just to be able to tell whether or not they succeeded? |
We are talking about a different use case - at least based on how error handling currently works, where Apart from that, I don't understand what you're asking. |
@mklement0 That's really thin. If someone really wants to know if an error occurred when -ErrorAction Ignore is used, they should write their own script that doesn't use -ErrorAction Ignore. Give me a real world use case where someone would want to know if a benign error occurred in a command or script they invoked. You shouldn't care about that when you invoke a command, because at the moment you are invoking that command you are placing your trust that the author of that command will properly let you know if there was an error that you should care about. If you don't trust that, then you shouldn't be invoking that specific command. The whole point of -ErrorAction Ignore is to suppress errors. Suppression is of little use for scripts invoked via S.M.A.PowerShell if the invoker has to ignore .HadErrors and check the Errors collection every time (which will be empty). In fact, I'd wager that there are probably many C# binaries out there where PowerShell is invoked from C# with S.M.A.PowerShell that are buggy right now because they rely on .HadErrors identifying whether or not there were actually errors. I will log a separate issue for the .HadErrors/$? issue. |
Great, thanks. Other than that, I don't see a disagreement, unless I misunderstood your original comment. You do not want Note that I was talking about SilentlyContinue, not Ignore, in the - definitely exotic - alternative scenario I described. |
@mklement0 Whoops, you're right, I misread your previous reply. We're on the same page then. |
@Jaykul: While I'm still unclear on what you were asking, perhaps I can clarify on my end: Re logging in My concern fits into the larger issue of the existing, longstanding dichotomy with respect to how non-terminating vs. terminating errors must be handled - see Our Error Handling, Ourselves - time to fully understand and properly document PowerShell's error handling. As @BrucePay has pointed out, As stated, Here's what > $Error.Clear(); Get-Item /NoSuchPath -ErrorAction Ignore -ErrorVariable ev; $Error.Count; "[$ev]"
0 # nothing was written to $Error
[] # nothing was captured in $ev Your proposal at least in part asks for the analogous behavior with respect to handling terminating errors, which must be done with It is the in part aspect that I find problematic: For symmetry, conceiving of If we only suppress filling the > $Error.Clear(); Invoke-Command { try {1 / 0} catch{} } -ErrorVariable ev; $Error.Count; "[$ev]"
1 # $Error was still written to, unlike with -ErrorAction Ignore
[] # in the future: $ev was not assigned to Hence my suggestion to not only suppress assigning to the Re @KirkMunro then took a step back to bring up a conceptually related issue, arguing that My aside re Taking another step back: |
I think we're in agreement. My request is focused on ErrorVariable only because I was focused on error detection in a script. That is, I wasn't concerned with In general, I think it's useless to check For what it's worth, I would agree that exceptions that are handled in a catch could be left out of |
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically. Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original. |
1 similar comment
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically. Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original. |
@kilasuit Please reopen, the issue is unresolved, but triaged and up-for-grabs. |
When you use try/catch and handle an exception, it still shows up in the global
$Error
, and more importantly, in the ErrorVariable.Is there any way to actually prevent handled exceptions from leaking into the ErrorVariable? Is there any way for a caller to determine that they are not, in fact, errors, but expected results that were dealt with by the function? That is, how does a caller distinguish the errors that matter?
Consider a simple example:
How can I stop the error variable from containing these things that I explicitly handled?
The text was updated successfully, but these errors were encountered: