-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Get-Content throws improved error when targeting a container #7797
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
Conversation
Fix for Issue #7770
CodeFactor fix
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.
I think the fix should be in GetContentReaders() or even in ResolvePaths().
|
|
||
| It "Should throw error on a directory with specific message" { | ||
| { Get-Content . -ErrorAction Stop } | | ||
| Should -Throw "Unable to access '.' contents as it is a container. Please use 'Get-ChildItem .' instead." |
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 never test a message because of localization. Please remove.
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.
Sure, will remove the tests, and it was not put in a new BeginProcessing() or GetContentReadres() as we already have other check for verifying Tail and Header coexistence, So I thought to put it before GetContentReadres().
|
Please look Set-Content. We have |
Enhanced error message for Get-Content Set-Content Clear-Content Add-Content
CodeFactor fix
|
@kvprasoon it seems more complicated than it seemed at first. The *-Content cmdlets do path expansion and we should test directory existence after the wilcard expansion. Complexity is that these cmdlets use different paths for path expansion. So I suggest exclude Clear-Content and fix it in new PR. |
Reverting Clear-content changes as this will be done in a seperate PR.
|
@iSazonov I think CI failures are not related to current code changes. |
iSazonov
left a comment
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 resolve a merge conflict.
| string errMsg = StringUtil.Format(SessionStateStrings.GetContainerContentException, path); | ||
| ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "GetContainerContentException", ErrorCategory.InvalidOperation, null); | ||
| WriteError(error); | ||
| return results; |
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.
Below we call SessionState.Path.GetResolvedPSPathFromPSPath() which can return array of paths including containers.
I'd consider line 614 to the fix.
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 issue is provider specific (basically any provider that implements IContentCmdletProvider). Looking in our code base, it seems the only public provider that's affected is the FileSystemProvider. The fix should be in in this method.
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.
Then GetContentWriter should be fixed too.
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.
@SteveL-MSFT fix in that method will address only for Get-Content cmdlet. How about Set/Add/Clear-Content cmdlets ? Do we need to make PRs for each of those cmdelts ?
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.
@kvprasoon yes, we should fix those at the same time if possible as I imagine the change to be very similar. I haven't looked at the code closely to see if there's a single point to make the change, but I suspect probably not.
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.
Single method what is identified is ResolvePaths() for *-Content cmdlets except for Clear-Content
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.
ResolvePaths() in ContentCommandBase.cs would not be the right place as we'd specialize that generic code path that calls into providers to a specific provider.
| return; | ||
| } | ||
|
|
||
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 fix the line.
| } | ||
|
|
||
| It "should throw 'GetContainerContentException' when -Path is a container" { | ||
| { Add-Content -Path . -Value "GetContainerContentException" -ErrorAction Stop } | Should -Throw -ErrorId "GetContainerContentException,Microsoft.PowerShell.Commands.AddContentCommand" |
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 "Add" in cmdlet name the "GetContainerContentException" does not look very good.
| <value>The dynamic parameters for the GetContentWriter operation cannot be retrieved for the '{0}' provider for path '{1}'. {2}</value> | ||
| </data> | ||
| <data name="GetContainerContentException" xml:space="preserve"> | ||
| <value>Unable to access '{0}' contents as it is a container. Please use 'Get-ChildItem {0}' instead.</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.
Thanks for taking this on. Given that this message is specific to the filesystem provider, I suggest using directory instead of container for clarity. Perhaps something like the following?
'{0}' is a directory, not a file. To list the items contained in a directory, use Get-ChildItem.
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.
@mklement0 sounds good, will change it the container part. I believe giving Get-ChildItem <the input path> in error message will be more helpful than just giving the cmdlet name to use.
your thoughts ?
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.
Thanks.
I personally think it's cleaner (less noisy) without the path, and is generally better to be concise in error message - without leaving out vital information, obviously, which is always a balancing act.
In this particular case, if the user managed to call Get-Content someDir and ran into the error, I think they 'll be able to infer from mentioning only the name of the cmdlet how to apply it analogously.
I don't feel strongly about this, however.
@SteveL-MSFT, 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.
This is provider specific issue and it appears only the FileSystemProvider supports IContentCmdletProvider. I think the error string should be in FileSystem Provider resx and I'm fine with @mklement0's suggested error message.
| string errMsg = StringUtil.Format(SessionStateStrings.GetContainerContentException, path); | ||
| ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "GetContainerContentException", ErrorCategory.InvalidOperation, null); | ||
| WriteError(error); | ||
| return results; |
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 issue is provider specific (basically any provider that implements IContentCmdletProvider). Looking in our code base, it seems the only public provider that's affected is the FileSystemProvider. The fix should be in in this method.
| <value>The dynamic parameters for the GetContentWriter operation cannot be retrieved for the '{0}' provider for path '{1}'. {2}</value> | ||
| </data> | ||
| <data name="GetContainerContentException" xml:space="preserve"> | ||
| <value>Unable to access '{0}' contents as it is a container. Please use 'Get-ChildItem {0}' instead.</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.
This is provider specific issue and it appears only the FileSystemProvider supports IContentCmdletProvider. I think the error string should be in FileSystem Provider resx and I'm fine with @mklement0's suggested error message.
|
Closing this PR, need to rebase my fork and will do the changes in different PRs. |
PR Summary
Fix #7770
Fix #2686
Enhancing the error message as per #7770 and #2686
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files 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