-
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
Throw error on entering non-existing type in Get-FormatData #7434
Conversation
@@ -169,27 +171,41 @@ protected override void ProcessRecord() | |||
viewList.Add(formatdef); | |||
}// foreach(ViewDefinition... | |||
|
|||
// write out all the available type definitions | |||
foreach (var pair in typedefs) | |||
// If no Type Definitions are found for _typename throw a terminating error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove obvious comment.
} | ||
else | ||
{ | ||
// write out all the available type definitions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove obvious comment.
var typeNames = pair.Key; | ||
|
||
if (writeOldWay) | ||
// All files must have the same extension otherwise throw. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the comment is unneeded. I believe we should remove it. (Or move to the method description).
@@ -4,6 +4,8 @@ | |||
using System; | |||
using System.Linq; | |||
using System.Management.Automation; | |||
using System.Management.Automation.Internal; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please alphabetically resort all using-s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this already sorted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have other using-s below.
It is minor comment.
Seems we could use TypeLoadException |
Some of those obvious comments were already there, so I didn't mess with them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@faraazahmad Thanks for you contribution!
@mklement0 Is the fix good for you? |
if (writeOldWay) | ||
ErrorRecord errorRecord = new ErrorRecord( | ||
new TypeLoadException("No such type could be found"), | ||
"SPECIFIED_TYPE_NOT_FOUND", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the FullQualifiedErrorId, the convention is to use Pascal casing: SpecifiedTypeNotFound.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, @SteveL-MSFT.
Additionally, it should be a non-terminating error, given that the cmdlet accepts multiple inputs and potentially produces multiple outputs.
@faraazahmad: I know I suggested ResourceUnavailable
initially, but on further reflection it probably isn't the right category.
We can use Remove-TypeData
as a model, which already reports an error (also non-terminating), and uses category InvalidOperation
:
PS> Remove-TypeData NoSuchType
Remove-TypeData : Error in TypeData "NoSuchType": The type "NoSuchType" was not found. The type name value must be the full name of the type. Verify the type name and run the command again.
At line:1 char:1
+ Remove-TypeData NoSuchType
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Remove-TypeData], RuntimeException
+ FullyQualifiedErrorId : TypesDynamicRemoveException,Microsoft.PowerShell.Commands.RemoveTypeDataCommand
As an aside: I'm not sure TypesDynamicRemoveException
was a great choice of error ID.
@SteveL-MSFT, @iSazonov, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should be a non-terminating error if multiple are accepted so no need to stop the entire operation. Agree that TypesDynamicRemoveException
is a bad error id, but it's a breaking change to change it now as the intent of the FQEI is to make it internet searchable. For symmetry, it makes sense to use InvalidOperation
and probably makes more sense for an end user whereas TypeLoadException
is more dev-centric.
@SteveL-MSFT I added new commit to address your comment, please update your review. |
|
||
if (writeOldWay) | ||
ErrorRecord errorRecord = new ErrorRecord( | ||
new TypeLoadException("No such type could be found"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exception message string should come from the resource file; UtilityCommonStrings.resx is probably the best location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@SteveL-MSFT @dantraMSFT Please update your review. |
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | ||
</resheader> | ||
<data name="SpecifiedTypeNotFound" xml:space="preserve"> | ||
<value>Cannot find the type.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably be something like:
The type name '{0}' could not be found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than Steve's recommendation about including the type name in the error message string, LGTM
HANG ON ... This is a breaking change to the function!!! Does |
@Jaykul this is a non-terminating error |
@SteveL-MSFT it still breaks code like this, right? if(!(Get-FormatData $Type)) {
Update-FormatData -TypeName $Type ...
} I mean, in the sense that we now get an error where there was none, even though the user had deliberately handled the situation correctly the way the cmdlet worked before. Are we only doing this because we think nobody uses it, or would you accept a PR for This command follows the exact same semantics as |
Yes, for someone who relied on the previous de facto behavior, this would be a breaking change. That in itself may be reason enough to not make the change - I have no sense of and have made no attempt to assess the real-world impact. What do you think the real-world impact is? On the other end of the spectrum: any bug fix is a breaking change: what used to break / work nonsensically before now no longer does. But let us be clear re:
Correctly in this situation means:
And, indeed, the same applies to the current behavior of
In that vein: either yes, or document the surprising existing behavior - see #7498 As an aside:
Unless you're referring to |
It's ironic that I'm the one arguing this -- I argued rather passionately against the no-output, no-error design pattern years ago in a discussion on the PowerShell MVP mailing list! Although at the time, my argument was specifically against commands that behave differently when you have a simple name, versus a wildcard (thus allowing the possibility of multiple items). Ultimately I was rather deluged with examples from the broader ecosystem (Exchange, SCSM, etc.) showing examples of commands quietly returning nothing when they could have returned many things. My point is that this is how PowerShell commands behave, in general: If the command can return MULTIPLE items, then when there is nothing to return, they just return nothing. That's a deliberate design choice.And yes, you're wrong @mklement0, when you say that those commands don't return multiple items with simple parameters. Here are some concrete examples. # There are about *eight* default rules that affect ScriptInfo, for example:
Get-FormatData System.Management.Automation.ScriptInfo
# Users can have multiple versions of the same module imported because of dependencies.
# We can import multiple versions of Pester as an example...
# (most of us have 3.4.0 and a newer one, right?):
Get-Module Pester -ListAvailable | Import-Module
Get-Module Pester But it's not just those, most of the default During the first command of your session, there's no history (or, do
|
I hear you, but let me ask you this before I address your examples:
|
They make sense:
Obviously in a lot of these cases, it's very clear that there's not an error. That is (if you understood the situation), you didn't actually expect there to be any child items, history, jobs, content, sessions, etc... I think all of them are examples of the rule, and serve to show that this cmdlet was correct without the PR. For what it's worth: If we were willing to break the backward compatibility of PowerShell, then I would be happy to argue again this design pattern and try to convince the world that all commands should have the same output behavior regardless of how many items they might output:
But in reality, changing this behavior across all the built-in commands would break too much, and there's no way to actually "fix" it because too many commands are outside the control of this team. We should therefore not alter the expectations of design, and thus, should not change commands. |
I have to agree with @Jaykul , this makes sense. For example, if I |
The issue is not about output behavior, so what I should've said earlier is: unless you explicitly opt in with switches such as The issue is that if you're asking for a specific entity by its literal name (as opposed to a wildcard pattern), not finding that entity should be an error. (By contrast, a wildcard pattern quietly producing no output if no matches are found makes sense ( This is how it currently works in most cmdlets, To quote @BrucePay from the
None of @Jaykul's other examples therefore apply:
|
If this fix is ultimately kept, I suggest amending the error message in 2 ways:
Therefore, instead of
|
@PowerShell/powershell-committee discussed this and we also discussed it in this morning's Community Call. We agreed that the intent is that if a literal is passed and is not found, it should return a non-terminating error. Cmdlets that don't have this behavior have bugs. In cases where it's explicit or implicit filtering, it should return nothing. We also agreed that we should revert this change and revisit making cmdlets consistent in 6.2. Finally, the real issue is that we are missing Test-* cmdlets so users had to rely on current behavior with Get-* cmdlets to see if something exists and we should add those cmdlets in the future. |
I think you're going to break so very many things -- that 6.2 needs to be 7.0 to be semantic |
Lord have mercy... once you do this, WPS and CPS are completely different languages that just happen to be related. Forget about moving scripts between the two. |
I heard today in the @PowerShell/powershell-committee Community Call that we're going to revert this and work towards consistency and @SteveL-MSFT if we agree that's the case, will the revert make RC? GA? |
The @PowerShell/powershell-maintainers will be reverting this commit, but that won't happen for RC where we are already in process of release but will make it for GA. @iSazonov if you are available, can you revert this as the other maintainers are working on the release? |
…owerShell#7434)" This reverts commit b754cd8.
…7434)" (#7546) Revert "Throw error on entering non-existing type in Get-FormatData (#7434) This reverts commit b754cd8. Per this comment #7434 (comment)
@SteveL-MSFT The commit already reverted by @TravisEz13 Have we a tracking issue to address the PowerShell Committee conclusion about Get-* and Test-* cmdlets. |
Didn't know my first contribution to Powershell could stir up so back and forth 😅. Is it safe to delete the branch? |
@faraazahmad I think it's a healthy discussion. Yes, you can delete the branch. |
Fix #4235
PR Summary
Write non-terminating error when
Get-FormatData
doesn't found a type definition for the provided type,PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
to the beginning of the title and remove the prefix when the PR is ready.[feature]
if the change is significant or affects feature tests