Skip to content

Commit 41c7cd7

Browse files
authored
Fix the error message in Hashtable-to-object conversion (PowerShell#17329)
1 parent f6ac9bb commit 41c7cd7

File tree

3 files changed

+58
-7
lines changed

3 files changed

+58
-7
lines changed

src/System.Management.Automation/engine/LanguagePrimitives.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,11 @@ public static class LanguagePrimitives
310310

311311
internal static void CreateMemberNotFoundError(PSObject pso, DictionaryEntry property, Type resultType)
312312
{
313-
string availableProperties = GetAvailableProperties(pso);
313+
string settableProperties = GetSettableProperties(pso);
314314

315-
string message = StringUtil.Format(ExtendedTypeSystem.PropertyNotFound, property.Key.ToString(), resultType.FullName, availableProperties);
315+
string message = settableProperties == string.Empty
316+
? StringUtil.Format(ExtendedTypeSystem.NoSettableProperty, property.Key.ToString(), resultType.FullName)
317+
: StringUtil.Format(ExtendedTypeSystem.PropertyNotFound, property.Key.ToString(), resultType.FullName, settableProperties);
316318

317319
typeConversion.WriteLine("Issuing an error message about not being able to create an object from hashtable.");
318320
throw new InvalidOperationException(message);
@@ -4735,18 +4737,23 @@ internal static PSObject SetObjectProperties(object o, IDictionary properties, T
47354737
return pso;
47364738
}
47374739

4738-
private static string GetAvailableProperties(PSObject pso)
4740+
private static string GetSettableProperties(PSObject pso)
47394741
{
4742+
if (pso is null || pso.Properties is null)
4743+
{
4744+
return string.Empty;
4745+
}
4746+
47404747
StringBuilder availableProperties = new StringBuilder();
47414748
bool first = true;
47424749

4743-
if (pso != null && pso.Properties != null)
4750+
foreach (PSPropertyInfo p in pso.Properties)
47444751
{
4745-
foreach (PSPropertyInfo p in pso.Properties)
4752+
if (p.IsSettable)
47464753
{
47474754
if (!first)
47484755
{
4749-
availableProperties.Append(" , ");
4756+
availableProperties.Append(", ");
47504757
}
47514758

47524759
availableProperties.Append("[" + p.Name + " <" + p.TypeNameOfValue + ">]");

src/System.Management.Automation/resources/ExtendedTypeSystem.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,10 @@
352352
<value>"{0}" returned a null value.</value>
353353
</data>
354354
<data name="PropertyNotFound" xml:space="preserve">
355-
<value>The {0} property was not found for the {1} object. The available property is: {2}</value>
355+
<value>The property '{0}' was not found for the '{1}' object. The settable properties are: {2}.</value>
356+
</data>
357+
<data name="NoSettableProperty" xml:space="preserve">
358+
<value>The property '{0}' was not found for the '{1}' object. There is no settable property available.</value>
356359
</data>
357360
<data name="ObjectCreationError" xml:space="preserve">
358361
<value>Cannot create object of type "{0}". {1}</value>

test/powershell/Language/Scripting/HashtableToPSCustomObjectConversion.Tests.ps1

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,44 @@ Describe "Tests for hashtable to PSCustomObject conversion" -Tags "CI" {
142142
}
143143
}
144144

145+
Describe "Error message with settable Property information" {
146+
BeforeAll {
147+
Add-Type @"
148+
namespace HashtableConversionTest {
149+
public class AType {
150+
public string Name;
151+
public string Path { get; set; }
152+
public string Id { get; }
153+
}
154+
}
155+
"@
156+
}
157+
158+
It "Only settable properties are called out in the error message" {
159+
try {
160+
[HashtableConversionTest.AType]@{ key = 1 }
161+
} catch {
162+
$e = $_
163+
}
164+
165+
$e.FullyQualifiedErrorId | Should -BeExactly "ObjectCreationError"
166+
$e.Exception.Message.Contains("key") | Should -BeTrue
167+
$e.Exception.Message.Contains("Name") | Should -BeTrue
168+
$e.Exception.Message.Contains("Path") | Should -BeTrue
169+
$e.Exception.Message.Contains("Id") | Should -BeFalse
170+
}
171+
172+
It "Shows no property when there is no settable property" {
173+
try {
174+
[System.Collections.Specialized.OrderedDictionary]@{ key = 1 }
175+
} catch {
176+
$e = $_
177+
}
178+
179+
$type = [psobject].Assembly.GetType("ExtendedTypeSystem")
180+
$property = $type.GetProperty("NoSettableProperty", @("NonPublic", "Static"))
181+
$resString = $property.GetValue($null) -f 'key', 'System.Collections.Specialized.OrderedDictionary'
182+
183+
$e.Exception.Message | Should -BeLike "*$resString"
184+
}
185+
}

0 commit comments

Comments
 (0)