Skip to content

Conversation

@kvprasoon
Copy link
Contributor

@kvprasoon kvprasoon commented Sep 16, 2018

PR Summary

Fix #7770
Fix #2686

Enhancing the error message as per #7770 and #2686

PR Checklist

Fix for Issue #7770
CodeFactor fix
Copy link
Collaborator

@iSazonov iSazonov left a 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."
Copy link
Collaborator

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.

Copy link
Contributor Author

@kvprasoon kvprasoon Sep 17, 2018

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().

@iSazonov
Copy link
Collaborator

Please look Set-Content. We have access denied there for a container too. I believe we should consider the fix in ResolvePaths().

Enhanced error message for
Get-Content
Set-Content
Clear-Content
Add-Content
CodeFactor fix
@iSazonov
Copy link
Collaborator

@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.

@kvprasoon
Copy link
Contributor Author

kvprasoon commented Sep 19, 2018

@iSazonov I think CI failures are not related to current code changes.

Copy link
Collaborator

@iSazonov iSazonov left a 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;
Copy link
Collaborator

@iSazonov iSazonov Sep 19, 2018

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.

Copy link
Member

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

@kvprasoon kvprasoon Sep 19, 2018

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 ?

Copy link
Member

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.

Copy link
Contributor Author

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

Copy link
Member

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.

@kvprasoon kvprasoon mentioned this pull request Sep 19, 2018
11 tasks
return;
}

Copy link
Collaborator

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"
Copy link
Collaborator

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>
Copy link
Contributor

@mklement0 mklement0 Sep 19, 2018

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.

Copy link
Contributor Author

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 ?

Copy link
Contributor

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?

Copy link
Member

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.

@SteveL-MSFT SteveL-MSFT changed the title Fix for Issue #7770 Get-Content throws improved error when targeting a container Sep 19, 2018
string errMsg = StringUtil.Format(SessionStateStrings.GetContainerContentException, path);
ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "GetContainerContentException", ErrorCategory.InvalidOperation, null);
WriteError(error);
return results;
Copy link
Member

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>
Copy link
Member

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.

@kvprasoon
Copy link
Contributor Author

kvprasoon commented Sep 19, 2018

Closing this PR, need to rebase my fork and will do the changes in different PRs.
Thanks everyone for the review comments.

@kvprasoon kvprasoon closed this Sep 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Get-Content throws confusing error when targeting a container Bad error message when using Get-Content with a Directory

4 participants