Fix the error message in Hashtable-to-object conversion (#17329)

This commit is contained in:
Dongbo Wang 2022-05-16 14:55:00 -07:00 committed by GitHub
parent f6ac9bb604
commit 41c7cd79da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 7 deletions

View File

@ -310,9 +310,11 @@ namespace System.Management.Automation
internal static void CreateMemberNotFoundError(PSObject pso, DictionaryEntry property, Type resultType)
{
string availableProperties = GetAvailableProperties(pso);
string settableProperties = GetSettableProperties(pso);
string message = StringUtil.Format(ExtendedTypeSystem.PropertyNotFound, property.Key.ToString(), resultType.FullName, availableProperties);
string message = settableProperties == string.Empty
? StringUtil.Format(ExtendedTypeSystem.NoSettableProperty, property.Key.ToString(), resultType.FullName)
: StringUtil.Format(ExtendedTypeSystem.PropertyNotFound, property.Key.ToString(), resultType.FullName, settableProperties);
typeConversion.WriteLine("Issuing an error message about not being able to create an object from hashtable.");
throw new InvalidOperationException(message);
@ -4735,18 +4737,23 @@ namespace System.Management.Automation
return pso;
}
private static string GetAvailableProperties(PSObject pso)
private static string GetSettableProperties(PSObject pso)
{
if (pso is null || pso.Properties is null)
{
return string.Empty;
}
StringBuilder availableProperties = new StringBuilder();
bool first = true;
if (pso != null && pso.Properties != null)
foreach (PSPropertyInfo p in pso.Properties)
{
foreach (PSPropertyInfo p in pso.Properties)
if (p.IsSettable)
{
if (!first)
{
availableProperties.Append(" , ");
availableProperties.Append(", ");
}
availableProperties.Append("[" + p.Name + " <" + p.TypeNameOfValue + ">]");

View File

@ -352,7 +352,10 @@
<value>"{0}" returned a null value.</value>
</data>
<data name="PropertyNotFound" xml:space="preserve">
<value>The {0} property was not found for the {1} object. The available property is: {2}</value>
<value>The property '{0}' was not found for the '{1}' object. The settable properties are: {2}.</value>
</data>
<data name="NoSettableProperty" xml:space="preserve">
<value>The property '{0}' was not found for the '{1}' object. There is no settable property available.</value>
</data>
<data name="ObjectCreationError" xml:space="preserve">
<value>Cannot create object of type "{0}". {1}</value>

View File

@ -142,3 +142,44 @@ Describe "Tests for hashtable to PSCustomObject conversion" -Tags "CI" {
}
}
Describe "Error message with settable Property information" {
BeforeAll {
Add-Type @"
namespace HashtableConversionTest {
public class AType {
public string Name;
public string Path { get; set; }
public string Id { get; }
}
}
"@
}
It "Only settable properties are called out in the error message" {
try {
[HashtableConversionTest.AType]@{ key = 1 }
} catch {
$e = $_
}
$e.FullyQualifiedErrorId | Should -BeExactly "ObjectCreationError"
$e.Exception.Message.Contains("key") | Should -BeTrue
$e.Exception.Message.Contains("Name") | Should -BeTrue
$e.Exception.Message.Contains("Path") | Should -BeTrue
$e.Exception.Message.Contains("Id") | Should -BeFalse
}
It "Shows no property when there is no settable property" {
try {
[System.Collections.Specialized.OrderedDictionary]@{ key = 1 }
} catch {
$e = $_
}
$type = [psobject].Assembly.GetType("ExtendedTypeSystem")
$property = $type.GetProperty("NoSettableProperty", @("NonPublic", "Static"))
$resString = $property.GetValue($null) -f 'key', 'System.Collections.Specialized.OrderedDictionary'
$e.Exception.Message | Should -BeLike "*$resString"
}
}